AzeorthCore 3.3.5a
OpenSource WoW Emulator
Loading...
Searching...
No Matches
Unit Class Referenceabstract

#include <Unit.h>

Inheritance diagram for Unit:
WorldObject Object WorldLocation Position Creature Player TempSummon Minion Guardian Puppet Totem Pet

Public Types

typedef std::unordered_set< Unit * > AttackerSet
 
typedef std::set< Unit * > ControlSet
 
typedef std::multimap< uint32, Aura * > AuraMap
 
typedef std::pair< AuraMap::const_iterator, AuraMap::const_iterator > AuraMapBounds
 
typedef std::pair< AuraMap::iterator, AuraMap::iterator > AuraMapBoundsNonConst
 
typedef std::multimap< uint32, AuraApplication * > AuraApplicationMap
 
typedef std::pair< AuraApplicationMap::const_iterator, AuraApplicationMap::const_iterator > AuraApplicationMapBounds
 
typedef std::pair< AuraApplicationMap::iterator, AuraApplicationMap::iterator > AuraApplicationMapBoundsNonConst
 
typedef std::multimap< AuraStateType, AuraApplication * > AuraStateAurasMap
 
typedef std::pair< AuraStateAurasMap::const_iterator, AuraStateAurasMap::const_iterator > AuraStateAurasMapBounds
 
typedef std::list< AuraEffect * > AuraEffectList
 
typedef std::list< Aura * > AuraList
 
typedef std::list< AuraApplication * > AuraApplicationList
 
typedef std::list< DiminishingReturnDiminishing
 
typedef GuidUnorderedSet ComboPointHolderSet
 
typedef std::map< uint8, AuraApplication * > VisibleAuraMap
 
typedef std::set< PetAura const * > PetAuraSet
 

Public Member Functions

 ~Unit () override
 
UnitAIGetAI ()
 
void SetAI (UnitAI *newAI)
 
void AddToWorld () override
 
void RemoveFromWorld () override
 
void CleanupBeforeRemoveFromMap (bool finalCleanup)
 
void CleanupsBeforeDelete (bool finalCleanup=true) override
 
uint32 GetDynamicFlags () const override
 
void ReplaceAllDynamicFlags (uint32 flag) override
 
DiminishingLevels GetDiminishing (DiminishingGroup group)
 
void IncrDiminishing (DiminishingGroup group)
 
float ApplyDiminishingToDuration (DiminishingGroup group, int32 &duration, Unit *caster, DiminishingLevels Level, int32 limitduration)
 
void ApplyDiminishingAura (DiminishingGroup group, bool apply)
 
void ClearDiminishings ()
 
float GetSpellMaxRangeForTarget (Unit const *target, SpellInfo const *spellInfo) const
 
float GetSpellMinRangeForTarget (Unit const *target, SpellInfo const *spellInfo) const
 
void Update (uint32 time) override
 
void setAttackTimer (WeaponAttackType type, int32 time)
 
void resetAttackTimer (WeaponAttackType type=BASE_ATTACK)
 
int32 getAttackTimer (WeaponAttackType type) const
 
bool isAttackReady (WeaponAttackType type=BASE_ATTACK) const
 
bool haveOffhandWeapon () const
 
bool CanDualWield () const
 
virtual void SetCanDualWield (bool value)
 
float GetCombatReach () const override
 
float GetMeleeReach () const
 
bool IsWithinRange (Unit const *obj, float dist) const
 
bool IsWithinCombatRange (Unit const *obj, float dist2compare) const
 
bool IsWithinMeleeRange (Unit const *obj, float dist=0.f) const
 
float GetMeleeRange (Unit const *target) const
 
virtual SpellSchoolMask GetMeleeDamageSchoolMask (WeaponAttackType attackType=BASE_ATTACK, uint8 damageIndex=0) const =0
 
bool GetRandomContactPoint (Unit const *target, float &x, float &y, float &z, bool force=false) const
 
void _addAttacker (Unit *pAttacker)
 
void _removeAttacker (Unit *pAttacker)
 
UnitgetAttackerForHelper () const
 
bool Attack (Unit *victim, bool meleeAttack)
 
void CastStop (uint32 except_spellid=0, bool withInstant=true)
 
bool AttackStop ()
 
void RemoveAllAttackers ()
 
AttackerSet const & getAttackers () const
 
bool GetMeleeAttackPoint (Unit *attacker, Position &pos)
 
bool isAttackingPlayer () const
 
UnitGetVictim () const
 
void CombatStop (bool includingCast=false)
 
void CombatStopWithPets (bool includingCast=false)
 
void StopAttackFaction (uint32 faction_id)
 
void StopAttackingInvalidTarget ()
 
UnitSelectNearbyTarget (Unit *exclude=nullptr, float dist=NOMINAL_MELEE_RANGE) const
 
UnitSelectNearbyNoTotemTarget (Unit *exclude=nullptr, float dist=NOMINAL_MELEE_RANGE) const
 
void SendMeleeAttackStop (Unit *victim=nullptr)
 
void SendMeleeAttackStart (Unit *victim, Player *sendTo=nullptr)
 
void AddUnitState (uint32 f)
 
bool HasUnitState (const uint32 f) const
 
void ClearUnitState (uint32 f)
 
uint32 GetUnitState () const
 
bool CanFreeMove () const
 
uint32 HasUnitTypeMask (uint32 mask) const
 
void AddUnitTypeMask (uint32 mask)
 
uint32 GetUnitTypeMask () const
 
bool IsSummon () const
 
bool IsGuardian () const
 
bool IsControllableGuardian () const
 
bool IsPet () const
 
bool IsHunterPet () const
 
bool IsTotem () const
 
bool IsVehicle () const
 
uint8 getLevel () const
 
uint8 getLevelForTarget (WorldObject const *) const override
 
void SetLevel (uint8 lvl, bool showLevelChange=true)
 
uint8 getRace (bool original=false) const
 
void setRace (uint8 race)
 
uint32 getRaceMask () const
 
uint8 getClass () const
 
uint32 getClassMask () const
 
uint8 getGender () const
 
float GetStat (Stats stat) const
 
void SetStat (Stats stat, int32 val)
 
uint32 GetArmor () const
 
void SetArmor (int32 val)
 
uint32 GetResistance (SpellSchools school) const
 
uint32 GetResistance (SpellSchoolMask mask) const
 
void SetResistance (SpellSchools school, int32 val)
 
uint32 GetHealth () const
 
uint32 GetMaxHealth () const
 
bool IsFullHealth () const
 
bool HealthBelowPct (int32 pct) const
 
bool HealthBelowPctDamaged (int32 pct, uint32 damage) const
 
bool HealthAbovePct (int32 pct) const
 
bool HealthAbovePctHealed (int32 pct, uint32 heal) const
 
float GetHealthPct () const
 
uint32 CountPctFromMaxHealth (int32 pct) const
 
uint32 CountPctFromCurHealth (int32 pct) const
 
float GetPowerPct (Powers power) const
 
void SetHealth (uint32 val)
 
void SetMaxHealth (uint32 val)
 
void SetFullHealth ()
 
int32 ModifyHealth (int32 val)
 
int32 GetHealthGain (int32 dVal)
 
Powers getPowerType () const
 
void setPowerType (Powers power)
 
uint32 GetPower (Powers power) const
 
uint32 GetMaxPower (Powers power) const
 
void SetPower (Powers power, uint32 val, bool withPowerUpdate=true)
 
void SetMaxPower (Powers power, uint32 val)
 
int32 ModifyPower (Powers power, int32 val, bool withPowerUpdate=true)
 
int32 ModifyPowerPct (Powers power, float pct, bool apply=true)
 
uint32 GetAttackTime (WeaponAttackType att) const
 
void SetAttackTime (WeaponAttackType att, uint32 val)
 
void ApplyAttackTimePercentMod (WeaponAttackType att, float val, bool apply)
 
void ApplyCastTimePercentMod (float val, bool apply)
 
UnitFlags GetUnitFlags () const
 
bool HasUnitFlag (UnitFlags flags) const
 
void SetUnitFlag (UnitFlags flags)
 
void RemoveUnitFlag (UnitFlags flags)
 
void ReplaceAllUnitFlags (UnitFlags flags)
 
UnitFlags2 GetUnitFlags2 () const
 
bool HasUnitFlag2 (UnitFlags2 flags) const
 
void SetUnitFlag2 (UnitFlags2 flags)
 
void RemoveUnitFlag2 (UnitFlags2 flags)
 
void ReplaceAllUnitFlags2 (UnitFlags2 flags)
 
SheathState GetSheath () const
 
virtual void SetSheath (SheathState sheathed)
 
uint32 GetFaction () const
 
void SetFaction (uint32 faction)
 
FactionTemplateEntry const * GetFactionTemplateEntry () const
 
ReputationRank GetReactionTo (Unit const *target, bool checkOriginalFaction=false) const
 
ReputationRank GetFactionReactionTo (FactionTemplateEntry const *factionTemplateEntry, Unit const *target) const
 
bool IsHostileTo (Unit const *unit) const
 
bool IsHostileToPlayers () const
 
bool IsFriendlyTo (Unit const *unit) const
 
bool IsNeutralToAll () const
 
bool IsInPartyWith (Unit const *unit) const
 
bool IsInRaidWith (Unit const *unit) const
 
void GetPartyMembers (std::list< Unit * > &units)
 
bool IsContestedGuard () const
 
bool IsInSanctuary () const
 
bool IsPvP () const
 
bool IsFFAPvP () const
 
void SetPvP (bool state)
 
uint32 GetCreatureType () const
 
uint32 GetCreatureTypeMask () const
 
uint8 getStandState () const
 
bool IsSitState () const
 
bool IsStandState () const
 
void SetStandState (uint8 state)
 
void SetStandFlags (uint8 flags)
 
void RemoveStandFlags (uint8 flags)
 
bool IsMounted () const
 
uint32 GetMountID () const
 
void Mount (uint32 mount, uint32 vehicleId=0, uint32 creatureEntry=0)
 
void Dismount ()
 
uint16 GetMaxSkillValueForLevel (Unit const *target=nullptr) const
 
void ProcDamageAndSpellFor (bool isVictim, Unit *target, uint32 procFlag, uint32 procExtra, WeaponAttackType attType, SpellInfo const *procSpellInfo, uint32 damage, SpellInfo const *procAura=nullptr, int8 procAuraEffectIndex=-1, Spell const *procSpell=nullptr, DamageInfo *damageInfo=nullptr, HealInfo *healInfo=nullptr, uint32 procPhase=2)
 
void GetProcAurasTriggeredOnEvent (std::list< AuraApplication * > &aurasTriggeringProc, std::list< AuraApplication * > *procAuras, ProcEventInfo eventInfo)
 
void TriggerAurasProcOnEvent (CalcDamageInfo &damageInfo)
 
void TriggerAurasProcOnEvent (std::list< AuraApplication * > *myProcAuras, std::list< AuraApplication * > *targetProcAuras, Unit *actionTarget, uint32 typeMaskActor, uint32 typeMaskActionTarget, uint32 spellTypeMask, uint32 spellPhaseMask, uint32 hitMask, Spell *spell, DamageInfo *damageInfo, HealInfo *healInfo)
 
void TriggerAurasProcOnEvent (ProcEventInfo &eventInfo, std::list< AuraApplication * > &procAuras)
 
void HandleEmoteCommand (uint32 emoteId)
 
void AttackerStateUpdate (Unit *victim, WeaponAttackType attType=BASE_ATTACK, bool extra=false, bool ignoreCasting=false)
 
void CalculateMeleeDamage (Unit *victim, CalcDamageInfo *damageInfo, WeaponAttackType attackType=BASE_ATTACK, const bool sittingVictim=false)
 
void DealMeleeDamage (CalcDamageInfo *damageInfo, bool durabilityLoss)
 
void HandleProcExtraAttackFor (Unit *victim, uint32 count)
 
void SetLastExtraAttackSpell (uint32 spellId)
 
uint32 GetLastExtraAttackSpell () const
 
void AddExtraAttacks (uint32 count)
 
void SetLastDamagedTargetGuid (ObjectGuid const &guid)
 
ObjectGuid const & GetLastDamagedTargetGuid () const
 
void CalculateSpellDamageTaken (SpellNonMeleeDamage *damageInfo, int32 damage, SpellInfo const *spellInfo, WeaponAttackType attackType=BASE_ATTACK, bool crit=false)
 
void DealSpellDamage (SpellNonMeleeDamage *damageInfo, bool durabilityLoss, Spell const *spell=nullptr)
 
float GetMeleeCritChanceReduction () const
 
float GetRangedCritChanceReduction () const
 
float GetSpellCritChanceReduction () const
 
uint32 GetMeleeCritDamageReduction (uint32 damage) const
 
uint32 GetRangedCritDamageReduction (uint32 damage) const
 
uint32 GetSpellCritDamageReduction (uint32 damage) const
 
uint32 GetMeleeDamageReduction (uint32 damage) const
 
uint32 GetRangedDamageReduction (uint32 damage) const
 
uint32 GetSpellDamageReduction (uint32 damage) const
 
float MeleeSpellMissChance (Unit const *victim, WeaponAttackType attType, int32 skillDiff, uint32 spellId) const
 
SpellMissInfo MeleeSpellHitResult (Unit *victim, SpellInfo const *spell)
 
SpellMissInfo MagicSpellHitResult (Unit *victim, SpellInfo const *spell)
 
SpellMissInfo SpellHitResult (Unit *victim, SpellInfo const *spell, bool canReflect=false)
 
SpellMissInfo SpellHitResult (Unit *victim, Spell const *spell, bool canReflect=false)
 
float GetUnitDodgeChance () const
 
float GetUnitParryChance () const
 
float GetUnitBlockChance () const
 
float GetUnitMissChance (WeaponAttackType attType) const
 
float GetUnitCriticalChance (WeaponAttackType attackType, Unit const *victim) const
 
int32 GetMechanicResistChance (SpellInfo const *spell)
 
bool CanUseAttackType (uint8 attacktype) const
 
virtual uint32 GetShieldBlockValue () const =0
 
uint32 GetShieldBlockValue (uint32 soft_cap, uint32 hard_cap) const
 
uint32 GetUnitMeleeSkill (Unit const *target=nullptr) const
 
uint32 GetDefenseSkillValue (Unit const *target=nullptr) const
 
uint32 GetWeaponSkillValue (WeaponAttackType attType, Unit const *target=nullptr) const
 
float GetWeaponProcChance () const
 
float GetPPMProcChance (uint32 WeaponSpeed, float PPM, SpellInfo const *spellProto) const
 
MeleeHitOutcome RollMeleeOutcomeAgainst (Unit const *victim, WeaponAttackType attType) const
 
MeleeHitOutcome RollMeleeOutcomeAgainst (Unit const *victim, WeaponAttackType attType, int32 crit_chance, int32 miss_chance, int32 dodge_chance, int32 parry_chance, int32 block_chance) const
 
NPCFlags GetNpcFlags () const
 
bool HasNpcFlag (NPCFlags flags) const
 
void SetNpcFlag (NPCFlags flags)
 
void RemoveNpcFlag (NPCFlags flags)
 
void ReplaceAllNpcFlags (NPCFlags flags)
 
bool IsVendor () const
 
bool IsTrainer () const
 
bool IsQuestGiver () const
 
bool IsGossip () const
 
bool IsTaxi () const
 
bool IsGuildMaster () const
 
bool IsBattleMaster () const
 
bool IsBanker () const
 
bool IsInnkeeper () const
 
bool IsSpiritHealer () const
 
bool IsSpiritGuide () const
 
bool IsTabardDesigner () const
 
bool IsAuctioner () const
 
bool IsArmorer () const
 
bool IsServiceProvider () const
 
bool IsSpiritService () const
 
bool IsCritter () const
 
bool IsInFlight () const
 
void SetImmuneToAll (bool apply, bool keepCombat=false)
 
bool IsImmuneToAll () const
 
void SetImmuneToPC (bool apply, bool keepCombat=false)
 
bool IsImmuneToPC () const
 
void SetImmuneToNPC (bool apply, bool keepCombat=false)
 
bool IsImmuneToNPC () const
 
bool IsEngaged () const
 
bool IsEngagedBy (Unit const *who) const
 
bool IsInCombat () const
 
bool IsInCombatWith (Unit const *who) const
 
bool IsPetInCombat () const
 
void CombatStart (Unit *target, bool initialAggro=true)
 
void CombatStartOnCast (Unit *target, bool initialAggro=true, uint32 duration=0)
 
void SetInCombatState (bool PvP, Unit *enemy=nullptr, uint32 duration=0)
 
void SetInCombatWith (Unit *enemy, uint32 duration=0)
 
void ClearInCombat ()
 
void ClearInPetCombat ()
 
uint32 GetCombatTimer () const
 
void SetCombatTimer (uint32 timer)
 
bool HasAuraTypeWithFamilyFlags (AuraType auraType, uint32 familyName, uint32 familyFlags) const
 
virtual bool HasSpell (uint32) const
 
bool HasBreakableByDamageAuraType (AuraType type, uint32 excludeAura=0) const
 
bool HasBreakableByDamageCrowdControlAura (Unit *excludeCasterChannel=nullptr) const
 
bool HasStealthAura () const
 
bool HasInvisibilityAura () const
 
bool isFeared () const
 
bool isInRoots () const
 
bool IsPolymorphed () const
 
bool isFrozen () const
 
bool isTargetableForAttack (bool checkFakeDeath=true, Unit const *byWho=nullptr) const
 
bool IsValidAttackTarget (Unit const *target) const
 
bool _IsValidAttackTarget (Unit const *target, SpellInfo const *bySpell, WorldObject const *obj=nullptr) const
 
bool IsValidAssistTarget (Unit const *target) const
 
bool _IsValidAssistTarget (Unit const *target, SpellInfo const *bySpell) const
 
virtual bool IsInWater () const
 
virtual bool IsUnderWater () const
 
bool isInAccessiblePlaceFor (Creature const *c) const
 
void SendHealSpellLog (Unit *victim, uint32 SpellID, uint32 Damage, uint32 OverHeal, uint32 Absorb, bool critical=false)
 
int32 HealBySpell (HealInfo &healInfo, bool critical=false)
 
void SendEnergizeSpellLog (Unit *victim, uint32 SpellID, uint32 Damage, Powers powertype)
 
void EnergizeBySpell (Unit *victim, uint32 SpellID, uint32 Damage, Powers powertype)
 
SpellCastResult CastSpell (SpellCastTargets const &targets, SpellInfo const *spellInfo, CustomSpellValues const *value, TriggerCastFlags triggerFlags=TRIGGERED_NONE, Item *castItem=nullptr, AuraEffect const *triggeredByAura=nullptr, ObjectGuid originalCaster=ObjectGuid::Empty)
 
SpellCastResult CastSpell (Unit *victim, uint32 spellId, bool triggered, Item *castItem=nullptr, AuraEffect const *triggeredByAura=nullptr, ObjectGuid originalCaster=ObjectGuid::Empty)
 
SpellCastResult CastSpell (Unit *victim, uint32 spellId, TriggerCastFlags triggerFlags=TRIGGERED_NONE, Item *castItem=nullptr, AuraEffect const *triggeredByAura=nullptr, ObjectGuid originalCaster=ObjectGuid::Empty)
 
SpellCastResult CastSpell (Unit *victim, SpellInfo const *spellInfo, bool triggered, Item *castItem=nullptr, AuraEffect const *triggeredByAura=nullptr, ObjectGuid originalCaster=ObjectGuid::Empty)
 
SpellCastResult CastSpell (Unit *victim, SpellInfo const *spellInfo, TriggerCastFlags triggerFlags=TRIGGERED_NONE, Item *castItem=nullptr, AuraEffect const *triggeredByAura=nullptr, ObjectGuid originalCaster=ObjectGuid::Empty)
 
SpellCastResult CastSpell (float x, float y, float z, uint32 spellId, bool triggered, Item *castItem=nullptr, AuraEffect const *triggeredByAura=nullptr, ObjectGuid originalCaster=ObjectGuid::Empty)
 
SpellCastResult CastSpell (GameObject *go, uint32 spellId, bool triggered, Item *castItem=nullptr, AuraEffect *triggeredByAura=nullptr, ObjectGuid originalCaster=ObjectGuid::Empty)
 
SpellCastResult CastCustomSpell (Unit *victim, uint32 spellId, int32 const *bp0, int32 const *bp1, int32 const *bp2, bool triggered, Item *castItem=nullptr, AuraEffect const *triggeredByAura=nullptr, ObjectGuid originalCaster=ObjectGuid::Empty)
 
SpellCastResult CastCustomSpell (uint32 spellId, SpellValueMod mod, int32 value, Unit *victim, bool triggered, Item *castItem=nullptr, AuraEffect const *triggeredByAura=nullptr, ObjectGuid originalCaster=ObjectGuid::Empty)
 
SpellCastResult CastCustomSpell (uint32 spellId, SpellValueMod mod, int32 value, Unit *victim=nullptr, TriggerCastFlags triggerFlags=TRIGGERED_NONE, Item *castItem=nullptr, AuraEffect const *triggeredByAura=nullptr, ObjectGuid originalCaster=ObjectGuid::Empty)
 
SpellCastResult CastCustomSpell (uint32 spellId, CustomSpellValues const &value, Unit *victim=nullptr, TriggerCastFlags triggerFlags=TRIGGERED_NONE, Item *castItem=nullptr, AuraEffect const *triggeredByAura=nullptr, ObjectGuid originalCaster=ObjectGuid::Empty)
 
AuraAddAura (uint32 spellId, Unit *target)
 
AuraAddAura (SpellInfo const *spellInfo, uint8 effMask, Unit *target)
 
void SetAuraStack (uint32 spellId, Unit *target, uint32 stack)
 
void SendPlaySpellVisual (uint32 id)
 
void SendPlaySpellImpact (ObjectGuid guid, uint32 id)
 
void BuildCooldownPacket (WorldPacket &data, uint8 flags, uint32 spellId, uint32 cooldown)
 
void BuildCooldownPacket (WorldPacket &data, uint8 flags, PacketCooldowns const &cooldowns)
 
void DeMorph ()
 
void SendAttackStateUpdate (CalcDamageInfo *damageInfo)
 
void SendAttackStateUpdate (uint32 HitInfo, Unit *target, uint8 SwingType, SpellSchoolMask damageSchoolMask, uint32 Damage, uint32 AbsorbDamage, uint32 Resist, VictimState TargetState, uint32 BlockedAmount)
 
void SendSpellNonMeleeDamageLog (SpellNonMeleeDamage *log)
 
void SendSpellNonMeleeReflectLog (SpellNonMeleeDamage *log, Unit *attacker)
 
void SendSpellNonMeleeDamageLog (Unit *target, SpellInfo const *spellInfo, uint32 Damage, SpellSchoolMask damageSchoolMask, uint32 AbsorbedDamage, uint32 Resist, bool PhysicalDamage, uint32 Blocked, bool CriticalHit=false, bool Split=false)
 
void SendPeriodicAuraLog (SpellPeriodicAuraLogInfo *pInfo)
 
void SendSpellMiss (Unit *target, uint32 spellID, SpellMissInfo missInfo)
 
void SendSpellDamageResist (Unit *target, uint32 spellId)
 
void SendSpellDamageImmune (Unit *target, uint32 spellId)
 
void NearTeleportTo (Position &pos, bool casting=false, bool vehicleTeleport=false, bool withPet=false, bool removeTransport=false)
 
void NearTeleportTo (float x, float y, float z, float orientation, bool casting=false, bool vehicleTeleport=false, bool withPet=false, bool removeTransport=false)
 
void SendTameFailure (uint8 result)
 
void SendTeleportPacket (Position &pos)
 
virtual bool UpdatePosition (float x, float y, float z, float ang, bool teleport=false)
 
bool UpdatePosition (const Position &pos, bool teleport=false)
 
void UpdateOrientation (float orientation)
 Only server-side orientation update, does not broadcast to client. More...
 
void UpdateHeight (float newZ)
 Only server-side height update, does not broadcast to client. More...
 
void KnockbackFrom (float x, float y, float speedXY, float speedZ)
 
void JumpTo (float speedXY, float speedZ, bool forward=true)
 
void JumpTo (WorldObject *obj, float speedZ)
 
void SendMonsterMove (float NewPosX, float NewPosY, float NewPosZ, uint32 TransitTime, SplineFlags sf=SPLINEFLAG_WALK_MODE)
 
void MonsterMoveWithSpeed (float x, float y, float z, float speed)
 
void SendMovementFlagUpdate (bool self=false)
 
virtual bool SetWalk (bool enable)
 
virtual bool SetDisableGravity (bool disable, bool packetOnly=false, bool updateAnimationTier=true)
 
virtual bool SetSwim (bool enable)
 
virtual bool SetCanFly (bool enable, bool packetOnly=false)
 
virtual bool SetWaterWalking (bool enable, bool packetOnly=false)
 
virtual bool SetFeatherFall (bool enable, bool packetOnly=false)
 
virtual bool SetHover (bool enable, bool packetOnly=false, bool updateAnimationTier=true)
 
void SendMovementWaterWalking (Player *sendTo)
 
void SendMovementFeatherFall (Player *sendTo)
 
void SendMovementHover (Player *sendTo)
 
void SetInFront (WorldObject const *target)
 
void SetFacingTo (float ori)
 
void SetFacingToObject (WorldObject *object)
 
void SendChangeCurrentVictimOpcode (HostileReference *pHostileReference)
 
void SendClearThreatListOpcode ()
 
void SendRemoveFromThreatListOpcode (HostileReference *pHostileReference)
 
void SendThreatListUpdate ()
 
void SendClearTarget ()
 
void BuildHeartBeatMsg (WorldPacket *data) const
 
bool IsAlive () const
 
bool isDying () const
 
bool isDead () const
 
DeathState getDeathState ()
 
virtual void setDeathState (DeathState s, bool despawn=false)
 
ObjectGuid GetOwnerGUID () const
 
void SetOwnerGUID (ObjectGuid owner)
 
ObjectGuid GetCreatorGUID () const
 
void SetCreatorGUID (ObjectGuid creator)
 
ObjectGuid GetMinionGUID () const
 
void SetMinionGUID (ObjectGuid guid)
 
ObjectGuid GetCharmerGUID () const
 
void SetCharmerGUID (ObjectGuid owner)
 
ObjectGuid GetCharmGUID () const
 
void SetPetGUID (ObjectGuid guid)
 
ObjectGuid GetPetGUID () const
 
void SetCritterGUID (ObjectGuid guid)
 
ObjectGuid GetCritterGUID () const
 
bool IsControlledByPlayer () const
 
bool IsCreatedByPlayer () const
 
ObjectGuid GetCharmerOrOwnerGUID () const
 
ObjectGuid GetCharmerOrOwnerOrOwnGUID () const
 
bool IsCharmedOwnedByPlayerOrPlayer () const
 
PlayerGetSpellModOwner () const
 
UnitGetOwner () const
 
GuardianGetGuardianPet () const
 
MinionGetFirstMinion () const
 
UnitGetCharmer () const
 
UnitGetCharm () const
 
UnitGetCharmerOrOwner () const
 
UnitGetCharmerOrOwnerOrSelf () const
 
PlayerGetCharmerOrOwnerPlayerOrPlayerItself () const
 
PlayerGetAffectingPlayer () const
 
void SetMinion (Minion *minion, bool apply)
 
void GetAllMinionsByEntry (std::list< Creature * > &Minions, uint32 entry)
 
void RemoveAllMinionsByEntry (uint32 entry)
 
void SetCharm (Unit *target, bool apply)
 
UnitGetNextRandomRaidMemberOrPet (float radius)
 
bool SetCharmedBy (Unit *charmer, CharmType type, AuraApplication const *aurApp=nullptr)
 
void RemoveCharmedBy (Unit *charmer)
 
void RestoreFaction ()
 
UnitGetFirstControlled () const
 
void RemoveAllControlled (bool onDeath=false)
 
bool IsCharmed () const
 
bool isPossessed () const
 
bool isPossessedByPlayer () const
 
bool isPossessing () const
 
bool isPossessing (Unit *u) const
 
CharmInfoGetCharmInfo ()
 
CharmInfoInitCharmInfo ()
 
void DeleteCharmInfo ()
 
void UpdateCharmAI ()
 
SharedVisionList const & GetSharedVisionList ()
 
void AddPlayerToVision (Player *player)
 
void RemovePlayerFromVision (Player *player)
 
bool HasSharedVision () const
 
void RemoveBindSightAuras ()
 
void RemoveCharmAuras ()
 
PetCreateTamedPetFrom (Creature *creatureTarget, uint32 spell_id=0)
 
PetCreateTamedPetFrom (uint32 creatureEntry, uint32 spell_id=0)
 
bool InitTamedPet (Pet *pet, uint8 level, uint32 spell_id)
 
Aura_TryStackingOrRefreshingExistingAura (SpellInfo const *newAura, uint8 effMask, Unit *caster, int32 *baseAmount=nullptr, Item *castItem=nullptr, ObjectGuid casterGUID=ObjectGuid::Empty, bool periodicReset=false)
 
void _AddAura (UnitAura *aura, Unit *caster)
 
AuraApplication_CreateAuraApplication (Aura *aura, uint8 effMask)
 
void _ApplyAuraEffect (Aura *aura, uint8 effIndex)
 
void _ApplyAura (AuraApplication *aurApp, uint8 effMask)
 
void _UnapplyAura (AuraApplicationMap::iterator &i, AuraRemoveMode removeMode)
 
void _UnapplyAura (AuraApplication *aurApp, AuraRemoveMode removeMode)
 
void _RemoveNoStackAuraApplicationsDueToAura (Aura *aura)
 
void _RemoveNoStackAurasDueToAura (Aura *aura)
 
bool _IsNoStackAuraDueToAura (Aura *appliedAura, Aura *existingAura) const
 
void _RegisterAuraEffect (AuraEffect *aurEff, bool apply)
 
AuraMapGetOwnedAuras ()
 
AuraMap const & GetOwnedAuras () const
 
void RemoveOwnedAura (AuraMap::iterator &i, AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT)
 
void RemoveOwnedAura (uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, uint8 reqEffMask=0, AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT)
 
void RemoveOwnedAura (Aura *aura, AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT)
 
AuraGetOwnedAura (uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, ObjectGuid itemCasterGUID=ObjectGuid::Empty, uint8 reqEffMask=0, Aura *except=nullptr) const
 
AuraApplicationMapGetAppliedAuras ()
 
AuraApplicationMap const & GetAppliedAuras () const
 
void RemoveAura (AuraApplicationMap::iterator &i, AuraRemoveMode mode=AURA_REMOVE_BY_DEFAULT)
 
void RemoveAura (uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, uint8 reqEffMask=0, AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT)
 
void RemoveAura (AuraApplication *aurApp, AuraRemoveMode mode=AURA_REMOVE_BY_DEFAULT)
 
void RemoveAura (Aura *aur, AuraRemoveMode mode=AURA_REMOVE_BY_DEFAULT)
 
void RemoveAppliedAuras (std::function< bool(AuraApplication const *)> const &check)
 
void RemoveOwnedAuras (std::function< bool(Aura const *)> const &check)
 
void RemoveAppliedAuras (uint32 spellId, std::function< bool(AuraApplication const *)> const &check)
 
void RemoveOwnedAuras (uint32 spellId, std::function< bool(Aura const *)> const &check)
 
void RemoveAurasDueToSpell (uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, uint8 reqEffMask=0, AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT)
 
void RemoveAuraFromStack (uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT)
 
void RemoveAurasDueToSpellByDispel (uint32 spellId, uint32 dispellerSpellId, ObjectGuid casterGUID, Unit *dispeller, uint8 chargesRemoved=1)
 
void RemoveAurasDueToSpellBySteal (uint32 spellId, ObjectGuid casterGUID, Unit *stealer)
 
void RemoveAurasDueToItemSpell (uint32 spellId, ObjectGuid castItemGuid)
 
void RemoveAurasByType (AuraType auraType, ObjectGuid casterGUID=ObjectGuid::Empty, Aura *except=nullptr, bool negative=true, bool positive=true)
 
void RemoveNotOwnSingleTargetAuras ()
 
void RemoveAurasWithInterruptFlags (uint32 flag, uint32 except=0, bool isAutoshot=false)
 
void RemoveAurasWithAttribute (uint32 flags)
 
void RemoveAurasWithFamily (SpellFamilyNames family, uint32 familyFlag1, uint32 familyFlag2, uint32 familyFlag3, ObjectGuid casterGUID)
 
void RemoveAurasWithMechanic (uint32 mechanic_mask, AuraRemoveMode removemode=AURA_REMOVE_BY_DEFAULT, uint32 except=0)
 
void RemoveMovementImpairingAuras (bool withRoot)
 
void RemoveAurasByShapeShift ()
 
void RemoveAreaAurasDueToLeaveWorld ()
 
void RemoveAllAuras ()
 
void RemoveArenaAuras ()
 
void RemoveAllAurasOnDeath ()
 
void RemoveAllAurasRequiringDeadTarget ()
 
void RemoveAllAurasExceptType (AuraType type)
 
void RemoveEvadeAuras ()
 
void DelayOwnedAuras (uint32 spellId, ObjectGuid caster, int32 delaytime)
 
void _RemoveAllAuraStatMods ()
 
void _ApplyAllAuraStatMods ()
 
AuraEffectList const & GetAuraEffectsByType (AuraType type) const
 
AuraListGetSingleCastAuras ()
 
AuraList const & GetSingleCastAuras () const
 
AuraEffectGetAuraEffect (uint32 spellId, uint8 effIndex, ObjectGuid casterGUID=ObjectGuid::Empty) const
 
AuraEffectGetAuraEffectOfRankedSpell (uint32 spellId, uint8 effIndex, ObjectGuid casterGUID=ObjectGuid::Empty) const
 
AuraEffectGetAuraEffect (AuraType type, SpellFamilyNames name, uint32 iconId, uint8 effIndex) const
 
AuraEffectGetAuraEffect (AuraType type, SpellFamilyNames family, uint32 familyFlag1, uint32 familyFlag2, uint32 familyFlag3, ObjectGuid casterGUID=ObjectGuid::Empty) const
 
AuraEffectGetAuraEffectDummy (uint32 spellid) const
 
AuraEffectGetDummyAuraEffect (SpellFamilyNames name, uint32 iconId, uint8 effIndex) const
 
AuraApplicationGetAuraApplication (uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, ObjectGuid itemCasterGUID=ObjectGuid::Empty, uint8 reqEffMask=0, AuraApplication *except=nullptr) const
 
AuraGetAura (uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, ObjectGuid itemCasterGUID=ObjectGuid::Empty, uint8 reqEffMask=0) const
 
AuraApplicationGetAuraApplicationOfRankedSpell (uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, ObjectGuid itemCasterGUID=ObjectGuid::Empty, uint8 reqEffMask=0, AuraApplication *except=nullptr) const
 
AuraGetAuraOfRankedSpell (uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, ObjectGuid itemCasterGUID=ObjectGuid::Empty, uint8 reqEffMask=0) const
 
void GetDispellableAuraList (Unit *caster, uint32 dispelMask, DispelChargesList &dispelList)
 
bool HasAuraEffect (uint32 spellId, uint8 effIndex, ObjectGuid caster=ObjectGuid::Empty) const
 
uint32 GetAuraCount (uint32 spellId) const
 
bool HasAura (uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, ObjectGuid itemCasterGUID=ObjectGuid::Empty, uint8 reqEffMask=0) const
 
bool HasAuraType (AuraType auraType) const
 
bool HasAuraTypeWithCaster (AuraType auratype, ObjectGuid caster) const
 
bool HasAuraTypeWithMiscvalue (AuraType auratype, int32 miscvalue) const
 
bool HasAuraTypeWithAffectMask (AuraType auratype, SpellInfo const *affectedSpell) const
 
bool HasAuraTypeWithValue (AuraType auratype, int32 value) const
 
bool HasAuraTypeWithTriggerSpell (AuraType auratype, uint32 triggerSpell) const
 
bool HasNegativeAuraWithInterruptFlag (uint32 flag, ObjectGuid guid=ObjectGuid::Empty)
 
bool HasVisibleAuraType (AuraType auraType) const
 
bool HasNegativeAuraWithAttribute (uint32 flag, ObjectGuid guid=ObjectGuid::Empty)
 
bool HasAuraWithMechanic (uint32 mechanicMask) const
 
AuraEffectIsScriptOverriden (SpellInfo const *spell, int32 script) const
 
uint32 GetDiseasesByCaster (ObjectGuid casterGUID, uint8 mode=0)
 
uint32 GetDoTsByCaster (ObjectGuid casterGUID) const
 
int32 GetTotalAuraModifierAreaExclusive (AuraType auratype) const
 
int32 GetTotalAuraModifier (AuraType auratype) const
 
float GetTotalAuraMultiplier (AuraType auratype) const
 
int32 GetMaxPositiveAuraModifier (AuraType auratype)
 
int32 GetMaxNegativeAuraModifier (AuraType auratype) const
 
int32 GetTotalAuraModifierByMiscMask (AuraType auratype, uint32 misc_mask) const
 
float GetTotalAuraMultiplierByMiscMask (AuraType auratype, uint32 misc_mask) const
 
int32 GetMaxPositiveAuraModifierByMiscMask (AuraType auratype, uint32 misc_mask, const AuraEffect *except=nullptr) const
 
int32 GetMaxNegativeAuraModifierByMiscMask (AuraType auratype, uint32 misc_mask) const
 
int32 GetTotalAuraModifierByMiscValue (AuraType auratype, int32 misc_value) const
 
float GetTotalAuraMultiplierByMiscValue (AuraType auratype, int32 misc_value) const
 
int32 GetMaxPositiveAuraModifierByMiscValue (AuraType auratype, int32 misc_value) const
 
int32 GetMaxNegativeAuraModifierByMiscValue (AuraType auratype, int32 misc_value) const
 
int32 GetTotalAuraModifierByAffectMask (AuraType auratype, SpellInfo const *affectedSpell) const
 
float GetTotalAuraMultiplierByAffectMask (AuraType auratype, SpellInfo const *affectedSpell) const
 
int32 GetMaxPositiveAuraModifierByAffectMask (AuraType auratype, SpellInfo const *affectedSpell) const
 
int32 GetMaxNegativeAuraModifierByAffectMask (AuraType auratype, SpellInfo const *affectedSpell) const
 
float GetResistanceBuffMods (SpellSchools school, bool positive) const
 
void SetResistanceBuffMods (SpellSchools school, bool positive, float val)
 
void ApplyResistanceBuffModsMod (SpellSchools school, bool positive, float val, bool apply)
 
void ApplyResistanceBuffModsPercentMod (SpellSchools school, bool positive, float val, bool apply)
 
void InitStatBuffMods ()
 
void ApplyStatBuffMod (Stats stat, float val, bool apply)
 
void ApplyStatPercentBuffMod (Stats stat, float val, bool apply)
 
void SetCreateStat (Stats stat, float val)
 
void SetCreateHealth (uint32 val)
 
uint32 GetCreateHealth () const
 
void SetCreateMana (uint32 val)
 
uint32 GetCreateMana () const
 
uint32 GetCreatePowers (Powers power) const
 
float GetPosStat (Stats stat) const
 
float GetNegStat (Stats stat) const
 
float GetCreateStat (Stats stat) const
 
void SetCurrentCastedSpell (Spell *pSpell)
 
virtual void ProhibitSpellSchool (SpellSchoolMask, uint32)
 
void InterruptSpell (CurrentSpellTypes spellType, bool withDelayed=true, bool withInstant=true, bool bySelf=false)
 
void FinishSpell (CurrentSpellTypes spellType, bool ok=true)
 
bool IsNonMeleeSpellCast (bool withDelayed, bool skipChanneled=false, bool skipAutorepeat=false, bool isAutoshoot=false, bool skipInstant=true) const
 
void InterruptNonMeleeSpells (bool withDelayed, uint32 spellid=0, bool withInstant=true, bool bySelf=false)
 
SpellGetCurrentSpell (CurrentSpellTypes spellType) const
 
SpellGetCurrentSpell (uint32 spellType) const
 
SpellFindCurrentSpellBySpellId (uint32 spell_id) const
 
int32 GetCurrentSpellCastTime (uint32 spell_id) const
 
virtual bool IsMovementPreventedByCasting () const
 
ShapeshiftForm GetShapeshiftForm () const
 
void SetShapeshiftForm (ShapeshiftForm form)
 
bool IsInFeralForm () const
 
bool IsInDisallowedMountForm () const
 
bool HandleStatModifier (UnitMods unitMod, UnitModifierType modifierType, float amount, bool apply)
 
void SetModifierValue (UnitMods unitMod, UnitModifierType modifierType, float value)
 
float GetModifierValue (UnitMods unitMod, UnitModifierType modifierType) const
 
float GetTotalStatValue (Stats stat, float additionalValue=0.0f) const
 
float GetTotalAuraModValue (UnitMods unitMod) const
 
SpellSchools GetSpellSchoolByAuraGroup (UnitMods unitMod) const
 
Stats GetStatByAuraGroup (UnitMods unitMod) const
 
Powers GetPowerTypeByAuraGroup (UnitMods unitMod) const
 
bool CanModifyStats () const
 
void SetCanModifyStats (bool modifyStats)
 
virtual bool UpdateStats (Stats stat)=0
 
virtual bool UpdateAllStats ()=0
 
virtual void UpdateResistances (uint32 school)=0
 
virtual void UpdateAllResistances ()
 
virtual void UpdateArmor ()=0
 
virtual void UpdateMaxHealth ()=0
 
virtual void UpdateMaxPower (Powers power)=0
 
virtual void UpdateAttackPowerAndDamage (bool ranged=false)=0
 
virtual void UpdateDamagePhysical (WeaponAttackType attType)
 
float GetTotalAttackPowerValue (WeaponAttackType attType, Unit *pVictim=nullptr) const
 
float GetWeaponDamageRange (WeaponAttackType attType, WeaponDamageRange type, uint8 damageIndex=0) const
 
void SetBaseWeaponDamage (WeaponAttackType attType, WeaponDamageRange damageRange, float value, uint8 damageIndex=0)
 
virtual void CalculateMinMaxDamage (WeaponAttackType attType, bool normalized, bool addTotalPct, float &minDamage, float &maxDamage, uint8 damageIndex=0)=0
 
uint32 CalculateDamage (WeaponAttackType attType, bool normalized, bool addTotalPct, uint8 itemDamagesMask=0)
 
float GetAPMultiplier (WeaponAttackType attType, bool normalized)
 
bool isInFrontInMap (Unit const *target, float distance, float arc=M_PI) const
 
bool isInBackInMap (Unit const *target, float distance, float arc=M_PI) const
 
bool IsVisible () const
 
void SetVisible (bool x)
 
void SetModelVisible (bool on)
 
uint32 GetPhaseByAuras () const
 
void SetPhaseMask (uint32 newPhaseMask, bool update) override
 
void UpdateObjectVisibility (bool forced=true, bool fromUpdate=false) override
 
bool CanHaveThreatList () const
 
void AddThreat (Unit *victim, float fThreat, SpellSchoolMask schoolMask=SPELL_SCHOOL_MASK_NORMAL, SpellInfo const *threatSpell=nullptr)
 
float ApplyTotalThreatModifier (float fThreat, SpellSchoolMask schoolMask=SPELL_SCHOOL_MASK_NORMAL)
 
void TauntApply (Unit *victim)
 
void TauntFadeOut (Unit *taunter)
 
ThreatMgrGetThreatMgr ()
 
ThreatMgr const & GetThreatMgr () const
 
void addHatedBy (HostileReference *pHostileReference)
 
void removeHatedBy (HostileReference *)
 
HostileRefMgrgetHostileRefMgr ()
 
VisibleAuraMap const * GetVisibleAuras ()
 
AuraApplicationGetVisibleAura (uint8 slot)
 
void SetVisibleAura (uint8 slot, AuraApplication *aur)
 
void RemoveVisibleAura (uint8 slot)
 
uint32 GetInterruptMask () const
 
void AddInterruptMask (uint32 mask)
 
void UpdateInterruptMask ()
 
uint32 GetDisplayId () const
 
virtual void SetDisplayId (uint32 modelId)
 
uint32 GetNativeDisplayId () const
 
void RestoreDisplayId ()
 
void SetNativeDisplayId (uint32 modelId)
 
void setTransForm (uint32 spellid)
 
uint32 getTransForm () const
 
void _RegisterDynObject (DynamicObject *dynObj)
 
void _UnregisterDynObject (DynamicObject *dynObj)
 
DynamicObjectGetDynObject (uint32 spellId)
 
bool RemoveDynObject (uint32 spellId)
 
void RemoveAllDynObjects ()
 
GameObjectGetGameObject (uint32 spellId) const
 
void AddGameObject (GameObject *gameObj)
 
void RemoveGameObject (GameObject *gameObj, bool del)
 
void RemoveGameObject (uint32 spellid, bool del)
 
void RemoveAllGameObjects ()
 
void ModifyAuraState (AuraStateType flag, bool apply)
 
uint32 BuildAuraStateUpdateForTarget (Unit *target) const
 
bool HasAuraState (AuraStateType flag, SpellInfo const *spellProto=nullptr, Unit const *Caster=nullptr) const
 
void UnsummonAllTotems (bool onDeath=false)
 
UnitGetMagicHitRedirectTarget (Unit *victim, SpellInfo const *spellInfo)
 
UnitGetMeleeHitRedirectTarget (Unit *victim, SpellInfo const *spellInfo=nullptr)
 
int32 SpellBaseDamageBonusDone (SpellSchoolMask schoolMask)
 
int32 SpellBaseDamageBonusTaken (SpellSchoolMask schoolMask, bool isDoT=false)
 
float SpellPctDamageModsDone (Unit *victim, SpellInfo const *spellProto, DamageEffectType damagetype)
 
uint32 SpellDamageBonusDone (Unit *victim, SpellInfo const *spellProto, uint32 pdamage, DamageEffectType damagetype, uint8 effIndex, float TotalMod=0.0f, uint32 stack=1)
 
uint32 SpellDamageBonusTaken (Unit *caster, SpellInfo const *spellProto, uint32 pdamage, DamageEffectType damagetype, uint32 stack=1)
 
int32 SpellBaseHealingBonusDone (SpellSchoolMask schoolMask)
 
int32 SpellBaseHealingBonusTaken (SpellSchoolMask schoolMask)
 
float SpellPctHealingModsDone (Unit *victim, SpellInfo const *spellProto, DamageEffectType damagetype)
 
uint32 SpellHealingBonusDone (Unit *victim, SpellInfo const *spellProto, uint32 healamount, DamageEffectType damagetype, uint8 effIndex, float TotalMod=0.0f, uint32 stack=1)
 
uint32 SpellHealingBonusTaken (Unit *caster, SpellInfo const *spellProto, uint32 healamount, DamageEffectType damagetype, uint32 stack=1)
 
uint32 MeleeDamageBonusDone (Unit *pVictim, uint32 damage, WeaponAttackType attType, SpellInfo const *spellProto=nullptr, SpellSchoolMask damageSchoolMask=SPELL_SCHOOL_MASK_NORMAL)
 
uint32 MeleeDamageBonusTaken (Unit *attacker, uint32 pdamage, WeaponAttackType attType, SpellInfo const *spellProto=nullptr, SpellSchoolMask damageSchoolMask=SPELL_SCHOOL_MASK_NORMAL)
 
bool isSpellBlocked (Unit *victim, SpellInfo const *spellProto, WeaponAttackType attackType=BASE_ATTACK)
 
bool isBlockCritical ()
 
float SpellDoneCritChance (Unit const *, SpellInfo const *spellProto, SpellSchoolMask schoolMask, WeaponAttackType attackType, bool skipEffectCheck) const
 
float SpellTakenCritChance (Unit const *caster, SpellInfo const *spellProto, SpellSchoolMask schoolMask, float doneChance, WeaponAttackType attackType, bool skipEffectCheck) const
 
void SetLastManaUse (uint32 spellCastTime)
 
bool IsUnderLastManaUseEffect () const
 
void SetContestedPvP (Player *attackedPlayer=nullptr, bool lookForNearContestedGuards=true)
 
uint32 GetCastingTimeForBonus (SpellInfo const *spellProto, DamageEffectType damagetype, uint32 CastingTime) const
 
float CalculateDefaultCoefficient (SpellInfo const *spellInfo, DamageEffectType damagetype) const
 
void CastDelayedSpellWithPeriodicAmount (Unit *caster, uint32 spellId, AuraType auraType, int32 addAmount, uint8 effectIndex=0)
 
void ApplySpellImmune (uint32 spellId, uint32 op, uint32 type, bool apply, SpellImmuneBlockType blockType=SPELL_BLOCK_TYPE_ALL)
 
void ApplySpellDispelImmunity (SpellInfo const *spellProto, DispelType type, bool apply)
 
virtual bool IsImmunedToSpell (SpellInfo const *spellInfo, Spell const *spell=nullptr)
 
bool IsImmunedToDamage (SpellSchoolMask meleeSchoolMask) const
 
bool IsImmunedToDamage (SpellInfo const *spellInfo) const
 
bool IsImmunedToDamage (Spell const *spell) const
 
bool IsImmunedToSchool (SpellSchoolMask meleeSchoolMask) const
 
bool IsImmunedToSchool (SpellInfo const *spellInfo) const
 
bool IsImmunedToSchool (Spell const *spell) const
 
bool IsImmunedToDamageOrSchool (SpellSchoolMask meleeSchoolMask) const
 
bool IsImmunedToDamageOrSchool (SpellInfo const *spellInfo) const
 
virtual bool IsImmunedToSpellEffect (SpellInfo const *spellInfo, uint32 index) const
 
void UpdateSpeed (UnitMoveType mtype, bool forced)
 
float GetSpeed (UnitMoveType mtype) const
 
float GetSpeedRate (UnitMoveType mtype) const
 
void SetSpeed (UnitMoveType mtype, float rate, bool forced=false)
 
void SetSpeedRate (UnitMoveType mtype, float rate)
 
float ApplyEffectModifiers (SpellInfo const *spellProto, uint8 effect_index, float value) const
 
int32 CalculateSpellDamage (Unit const *target, SpellInfo const *spellProto, uint8 effect_index, int32 const *basePoints=nullptr) const
 
int32 CalcSpellDuration (SpellInfo const *spellProto)
 
int32 ModSpellDuration (SpellInfo const *spellProto, Unit const *target, int32 duration, bool positive, uint32 effectMask)
 
void ModSpellCastTime (SpellInfo const *spellProto, int32 &castTime, Spell *spell=nullptr)
 
float CalculateLevelPenalty (SpellInfo const *spellProto) const
 
void addFollower (FollowerReference *pRef)
 
void removeFollower (FollowerReference *)
 
MotionMasterGetMotionMaster ()
 
const MotionMasterGetMotionMaster () const
 
virtual MovementGeneratorType GetDefaultMovementType () const
 -------—End of Pet responses methods-------— More...
 
bool IsStopped () const
 
void StopMoving ()
 
void StopMovingOnCurrentPos ()
 
virtual void PauseMovement (uint32 timer=0, uint8 slot=0)
 
void ResumeMovement (uint32 timer=0, uint8 slot=0)
 
void AddUnitMovementFlag (uint32 f)
 
void RemoveUnitMovementFlag (uint32 f)
 
bool HasUnitMovementFlag (uint32 f) const
 
uint32 GetUnitMovementFlags () const
 
void SetUnitMovementFlags (uint32 f)
 
void AddExtraUnitMovementFlag (uint16 f)
 
void RemoveExtraUnitMovementFlag (uint16 f)
 
uint16 HasExtraUnitMovementFlag (uint16 f) const
 
uint16 GetExtraUnitMovementFlags () const
 
void SetExtraUnitMovementFlags (uint16 f)
 
void SetControlled (bool apply, UnitState state)
 
void DisableRotate (bool apply)
 
void DisableSpline ()
 
uint8 GetComboPoints (Unit const *who=nullptr) const
 --------—Combo point system----------------— More...
 
uint8 GetComboPoints (ObjectGuid const &guid) const
 
UnitGetComboTarget () const
 
ObjectGuid const GetComboTargetGUID () const
 
void AddComboPoints (Unit *target, int8 count)
 
void AddComboPoints (int8 count)
 
void ClearComboPoints ()
 
void SendComboPoints ()
 
void AddComboPointHolder (Unit *unit)
 
void RemoveComboPointHolder (Unit *unit)
 
void ClearComboPointHolders ()
 
void SendPetActionFeedback (uint8 msg)
 -------—Pet responses methods--------------— More...
 
void SendPetTalk (uint32 pettalk)
 
void SendPetAIReaction (ObjectGuid guid)
 
void propagateSpeedChange ()
 -------—End of Pet responses methods-------— More...
 
void ClearAllReactives ()
 
void StartReactiveTimer (ReactiveType reactive)
 
void UpdateReactives (uint32 p_time)
 
void UpdateAuraForGroup (uint8 slot)
 
bool CanProc ()
 
void SetCantProc (bool apply)
 
void AddPetAura (PetAura const *petSpell)
 
void RemovePetAura (PetAura const *petSpell)
 
void CastPetAura (PetAura const *aura)
 
bool IsPetAura (Aura const *aura)
 
uint32 GetModelForForm (ShapeshiftForm form) const
 
uint32 GetModelForTotem (PlayerTotemType totemType)
 
void SetRedirectThreat (ObjectGuid guid, uint32 pct)
 
void ResetRedirectThreat ()
 
void ModifyRedirectThreat (int32 amount)
 
uint32 GetRedirectThreatPercent ()
 
UnitGetRedirectThreatTarget () const
 
bool CreateVehicleKit (uint32 id, uint32 creatureEntry)
 
void RemoveVehicleKit ()
 
VehicleGetVehicleKit () const
 
VehicleGetVehicle () const
 
bool IsOnVehicle (Unit const *vehicle) const
 
UnitGetVehicleBase () const
 
CreatureGetVehicleCreatureBase () const
 
ObjectGuid GetTransGUID () const override
 
TransportBaseGetDirectTransport () const
 Returns the transport this unit is on directly (if on vehicle and transport, return vehicle) More...
 
bool HandleSpellClick (Unit *clicker, int8 seatId=-1)
 
void EnterVehicle (Unit *base, int8 seatId=-1)
 
void EnterVehicleUnattackable (Unit *base, int8 seatId=-1)
 
void ExitVehicle (Position const *exitPosition=nullptr)
 
void ChangeSeat (int8 seatId, bool next=true)
 
void _ExitVehicle (Position const *exitPosition=nullptr)
 
void _EnterVehicle (Vehicle *vehicle, int8 seatId, AuraApplication const *aurApp=nullptr)
 
void BuildMovementPacket (ByteBuffer *data) const
 
virtual bool CanSwim () const
 this method checks the current flag of a unit More...
 
bool IsLevitating () const
 
bool IsWalking () const
 
bool isMoving () const
 
bool isTurning () const
 
bool IsHovering () const
 
bool isSwimming () const
 
virtual bool CanFly () const =0
 
bool IsFlying () const
 
bool IsFalling () const
 
float GetHoverHeight () const
 
virtual bool CanEnterWater () const =0
 
void RewardRage (uint32 damage, uint32 weaponSpeedHitFactor, bool attacker)
 
virtual float GetFollowAngle () const
 
void OutDebugInfo () const
 
virtual bool isBeingLoaded () const
 
bool IsDuringRemoveFromWorld () const
 
PetToPet ()
 
TotemToTotem ()
 
TempSummonToTempSummon ()
 
const TempSummonToTempSummon () const
 
void AddPointedBy (SafeUnitPointer *sup)
 
void RemovePointedBy (SafeUnitPointer *sup)
 
void ExecuteDelayedUnitRelocationEvent ()
 
void ExecuteDelayedUnitAINotifyEvent ()
 
virtual bool HasSpellCooldown (uint32) const
 
virtual bool HasSpellItemCooldown (uint32, uint32) const
 
virtual void AddSpellCooldown (uint32, uint32, uint32, bool needSendToClient=false, bool forceSendToSpectator=false)
 
bool CanApplyResilience () const
 
void PetSpellFail (SpellInfo const *spellInfo, Unit *target, uint32 result)
 
int32 CalculateAOEDamageReduction (int32 damage, uint32 schoolMask, Unit *caster) const
 
ObjectGuid GetTarget () const
 
virtual void SetTarget (ObjectGuid=ObjectGuid::Empty)=0
 
void SetInstantCast (bool set)
 
bool CanInstantCast () const
 
virtual void Talk (std::string_view text, ChatMsg msgType, Language language, float textRange, WorldObject const *target)
 
virtual void Say (std::string_view text, Language language, WorldObject const *target=nullptr)
 
virtual void Yell (std::string_view text, Language language, WorldObject const *target=nullptr)
 
virtual void TextEmote (std::string_view text, WorldObject const *target=nullptr, bool isBossEmote=false)
 
virtual void Whisper (std::string_view text, Language language, Player *target, bool isBossWhisper=false)
 
virtual void Talk (uint32 textId, ChatMsg msgType, float textRange, WorldObject const *target)
 
virtual void Say (uint32 textId, WorldObject const *target=nullptr)
 
virtual void Yell (uint32 textId, WorldObject const *target=nullptr)
 
virtual void TextEmote (uint32 textId, WorldObject const *target=nullptr, bool isBossEmote=false)
 
virtual void Whisper (uint32 textId, Player *target, bool isBossWhisper=false)
 
float GetCollisionHeight () const override
 Return collision height sent to client. More...
 
float GetCollisionWidth () const override
 this method gets the diameter of a Unit by DB if any value is defined, otherwise it gets the value by the DBC More...
 
float GetCollisionRadius () const override
 this method gets the radius of a Unit by DB if any value is defined, otherwise it gets the value by the DBC More...
 
void ProcessPositionDataChanged (PositionFullTerrainStatus const &data) override
 
virtual void ProcessTerrainStatusUpdate ()
 
bool CanRestoreMana (SpellInfo const *spellInfo) const
 
std::string GetDebugInfo () const override
 
- Public Member Functions inherited from WorldObject
 ~WorldObject () override
 
virtual void Update (uint32)
 
void _Create (ObjectGuid::LowType guidlow, HighGuid guidhigh, uint32 phaseMask)
 
void AddToWorld () override
 
void RemoveFromWorld () override
 
void GetNearPoint2D (WorldObject const *searcher, float &x, float &y, float distance, float absAngle, Position const *startPos=nullptr) const
 
void GetNearPoint2D (float &x, float &y, float distance, float absAngle, Position const *startPos=nullptr) const
 
void GetNearPoint (WorldObject const *searcher, float &x, float &y, float &z, float searcher_size, float distance2d, float absAngle, float controlZ=0, Position const *startPos=nullptr) const
 
void GetVoidClosePoint (float &x, float &y, float &z, float size, float distance2d=0, float relAngle=0, float controlZ=0) const
 
bool GetClosePoint (float &x, float &y, float &z, float size, float distance2d=0, float angle=0, WorldObject const *forWho=nullptr, bool force=false) const
 
void MovePosition (Position &pos, float dist, float angle)
 
Position GetNearPosition (float dist, float angle)
 
void MovePositionToFirstCollision (Position &pos, float dist, float angle)
 
Position GetFirstCollisionPosition (float startX, float startY, float startZ, float destX, float destY)
 
Position GetFirstCollisionPosition (float destX, float destY, float destZ)
 
Position GetFirstCollisionPosition (float dist, float angle)
 
Position GetRandomNearPosition (float radius)
 
void GetContactPoint (WorldObject const *obj, float &x, float &y, float &z, float distance2d=CONTACT_DISTANCE) const
 
void GetChargeContactPoint (WorldObject const *obj, float &x, float &y, float &z, float distance2d=CONTACT_DISTANCE) const
 
float GetObjectSize () const
 
virtual float GetCombatReach () const
 
void UpdateGroundPositionZ (float x, float y, float &z) const
 
void UpdateAllowedPositionZ (float x, float y, float &z, float *groundZ=nullptr) const
 
void GetRandomPoint (const Position &srcPos, float distance, float &rand_x, float &rand_y, float &rand_z) const
 
Position GetRandomPoint (const Position &srcPos, float distance) const
 
uint32 GetInstanceId () const
 
virtual void SetPhaseMask (uint32 newPhaseMask, bool update)
 
uint32 GetPhaseMask () const
 
bool InSamePhase (WorldObject const *obj) const
 
bool InSamePhase (uint32 phasemask) const
 
uint32 GetZoneId () const
 
uint32 GetAreaId () const
 
void GetZoneAndAreaId (uint32 &zoneid, uint32 &areaid) const
 
bool IsOutdoors () const
 
LiquidData const & GetLiquidData () const
 
InstanceScriptGetInstanceScript () const
 
std::string const & GetName () const
 
void SetName (std::string const &newname)
 
virtual std::string const & GetNameForLocaleIdx (LocaleConstant) const
 
float GetDistance (WorldObject const *obj) const
 
float GetDistance (const Position &pos) const
 
float GetDistance (float x, float y, float z) const
 
float GetDistance2d (WorldObject const *obj) const
 
float GetDistance2d (float x, float y) const
 
float GetDistanceZ (WorldObject const *obj) const
 
bool IsSelfOrInSameMap (WorldObject const *obj) const
 
bool IsInMap (WorldObject const *obj) const
 
bool IsWithinDist3d (float x, float y, float z, float dist) const
 
bool IsWithinDist3d (const Position *pos, float dist) const
 
bool IsWithinDist2d (float x, float y, float dist) const
 
bool IsWithinDist2d (const Position *pos, float dist) const
 
bool IsWithinDist (WorldObject const *obj, float dist2compare, bool is3D=true, bool useBoundingRadius=true) const
 
bool IsWithinDistInMap (WorldObject const *obj, float dist2compare, bool is3D=true, bool useBoundingRadius=true) const
 
bool IsWithinLOS (float x, float y, float z, VMAP::ModelIgnoreFlags ignoreFlags=VMAP::ModelIgnoreFlags::Nothing, LineOfSightChecks checks=LINEOFSIGHT_ALL_CHECKS) const
 
bool IsWithinLOSInMap (WorldObject const *obj, VMAP::ModelIgnoreFlags ignoreFlags=VMAP::ModelIgnoreFlags::Nothing, LineOfSightChecks checks=LINEOFSIGHT_ALL_CHECKS, Optional< float > collisionHeight={ }) const
 
Position GetHitSpherePointFor (Position const &dest, Optional< float > collisionHeight={ }) const
 
void GetHitSpherePointFor (Position const &dest, float &x, float &y, float &z, Optional< float > collisionHeight={ }) const
 
bool GetDistanceOrder (WorldObject const *obj1, WorldObject const *obj2, bool is3D=true) const
 
bool IsInRange (WorldObject const *obj, float minRange, float maxRange, bool is3D=true) const
 
bool IsInRange2d (float x, float y, float minRange, float maxRange) const
 
bool IsInRange3d (float x, float y, float z, float minRange, float maxRange) const
 
bool isInFront (WorldObject const *target, float arc=M_PI) const
 
bool isInBack (WorldObject const *target, float arc=M_PI) const
 
bool IsInBetween (WorldObject const *obj1, WorldObject const *obj2, float size=0) const
 
virtual void CleanupsBeforeDelete (bool finalCleanup=true)
 
virtual void SendMessageToSet (WorldPacket const *data, bool self) const
 
virtual void SendMessageToSetInRange (WorldPacket const *data, float dist, bool, bool includeMargin=false, Player const *skipped_rcvr=nullptr) const
 
virtual void SendMessageToSet (WorldPacket const *data, Player const *skipped_rcvr) const
 
virtual uint8 getLevelForTarget (WorldObject const *) const
 
void PlayDistanceSound (uint32 sound_id, Player *target=nullptr)
 
void PlayDirectSound (uint32 sound_id, Player *target=nullptr)
 
void PlayDirectMusic (uint32 music_id, Player *target=nullptr)
 
void SendObjectDeSpawnAnim (ObjectGuid guid)
 
virtual void SaveRespawnTime ()
 
void AddObjectToRemoveList ()
 
float GetGridActivationRange () const
 
float GetVisibilityRange () const
 
virtual float GetSightRange (WorldObject const *target=nullptr) const
 
bool CanSeeOrDetect (WorldObject const *obj, bool ignoreStealth=false, bool distanceCheck=false, bool checkAlert=false) const
 
void SendPlayMusic (uint32 Music, bool OnlySelf)
 
virtual void SetMap (Map *map)
 
virtual void ResetMap ()
 
MapGetMap () const
 
MapFindMap () const
 
void SetZoneScript ()
 
void ClearZoneScript ()
 
ZoneScriptGetZoneScript () const
 
TempSummonSummonCreature (uint32 id, const Position &pos, TempSummonType spwtype=TEMPSUMMON_MANUAL_DESPAWN, uint32 despwtime=0, uint32 vehId=0, SummonPropertiesEntry const *properties=nullptr) const
 
TempSummonSummonCreature (uint32 id, float x, float y, float z, float ang=0, TempSummonType spwtype=TEMPSUMMON_MANUAL_DESPAWN, uint32 despwtime=0, SummonPropertiesEntry const *properties=nullptr)
 
GameObjectSummonGameObject (uint32 entry, float x, float y, float z, float ang, float rotation0, float rotation1, float rotation2, float rotation3, uint32 respawnTime, bool checkTransport=true, GOSummonType summonType=GO_SUMMON_TIMED_OR_CORPSE_DESPAWN)
 
CreatureSummonTrigger (float x, float y, float z, float ang, uint32 dur, bool setLevel=false, CreatureAI *(*GetAI)(Creature *)=nullptr)
 
void SummonCreatureGroup (uint8 group, std::list< TempSummon * > *list=nullptr)
 
CreatureFindNearestCreature (uint32 entry, float range, bool alive=true) const
 
GameObjectFindNearestGameObject (uint32 entry, float range, bool onlySpawned=false) const
 
GameObjectFindNearestGameObjectOfType (GameobjectTypes type, float range) const
 
PlayerSelectNearestPlayer (float distance=0) const
 
void GetGameObjectListWithEntryInGrid (std::list< GameObject * > &lList, uint32 uiEntry, float fMaxSearchRange) const
 
void GetCreatureListWithEntryInGrid (std::list< Creature * > &lList, uint32 uiEntry, float fMaxSearchRange) const
 
void GetDeadCreatureListInGrid (std::list< Creature * > &lList, float maxSearchRange, bool alive=false) const
 
void DestroyForNearbyPlayers ()
 
virtual void UpdateObjectVisibility (bool forced=true, bool fromUpdate=false)
 
void BuildUpdate (UpdateDataMapType &data_map, UpdatePlayerSet &player_set) override
 
void GetCreaturesWithEntryInRange (std::list< Creature * > &creatureList, float radius, uint32 entry)
 
void SetPositionDataUpdate ()
 
void UpdatePositionData ()
 
void AddToObjectUpdate () override
 
void RemoveFromObjectUpdate () override
 
void AddToNotify (uint16 f)
 
void RemoveFromNotify (uint16 f)
 
bool isNeedNotify (uint16 f) const
 
uint16 GetNotifyFlags () const
 
bool NotifyExecuted (uint16 f) const
 
void SetNotified (uint16 f)
 
void ResetAllNotifies ()
 
bool isActiveObject () const
 
void setActive (bool isActiveObject)
 
bool IsFarVisible () const
 
bool IsVisibilityOverridden () const
 
void SetVisibilityDistanceOverride (VisibilityDistanceType type)
 
void SetWorldObject (bool apply)
 
bool IsPermanentWorldObject () const
 
bool IsWorldObject () const
 
bool IsInWintergrasp () const
 
TransportGetTransport () const
 
float GetTransOffsetX () const
 
float GetTransOffsetY () const
 
float GetTransOffsetZ () const
 
float GetTransOffsetO () const
 
uint32 GetTransTime () const
 
int8 GetTransSeat () const
 
virtual ObjectGuid GetTransGUID () const
 
void SetTransport (Transport *t)
 
virtual float GetStationaryX () const
 
virtual float GetStationaryY () const
 
virtual float GetStationaryZ () const
 
virtual float GetStationaryO () const
 
float GetMapWaterOrGroundLevel (float x, float y, float z, float *ground=nullptr) const
 
float GetMapHeight (float x, float y, float z, bool vmap=true, float distanceToSearch=50.0f) const
 
float GetFloorZ () const
 
float GetMinHeightInWater () const
 Get the minimum height of a object that should be in water to start floating/swim. More...
 
virtual float GetCollisionHeight () const
 
virtual float GetCollisionWidth () const
 
virtual float GetCollisionRadius () const
 
void AddAllowedLooter (ObjectGuid guid)
 
void ResetAllowedLooters ()
 
void SetAllowedLooters (GuidUnorderedSet const looters)
 
bool HasAllowedLooter (ObjectGuid guid) const
 
GuidUnorderedSet const & GetAllowedLooters () const
 
std::string GetDebugInfo () const override
 
- Public Member Functions inherited from Object
virtual ~Object ()
 
bool IsInWorld () const
 
virtual void AddToWorld ()
 
virtual void RemoveFromWorld ()
 
ObjectGuid GetGUID () const
 
PackedGuid const & GetPackGUID () const
 
uint32 GetEntry () const
 
void SetEntry (uint32 entry)
 
float GetObjectScale () const
 
virtual void SetObjectScale (float scale)
 
virtual uint32 GetDynamicFlags () const
 
bool HasDynamicFlag (uint32 flag) const
 
virtual void SetDynamicFlag (uint32 flag)
 
virtual void RemoveDynamicFlag (uint32 flag)
 
virtual void ReplaceAllDynamicFlags (uint32 flag)
 
TypeID GetTypeId () const
 
bool isType (uint16 mask) const
 
virtual void BuildCreateUpdateBlockForPlayer (UpdateData *data, Player *target) const
 
void SendUpdateToPlayer (Player *player)
 
void BuildValuesUpdateBlockForPlayer (UpdateData *data, Player *target) const
 
void BuildOutOfRangeUpdateBlock (UpdateData *data) const
 
void BuildMovementUpdateBlock (UpdateData *data, uint32 flags=0) const
 
virtual void DestroyForPlayer (Player *target, bool onDeath=false) const
 
int32 GetInt32Value (uint16 index) const
 
uint32 GetUInt32Value (uint16 index) const
 
uint64 GetUInt64Value (uint16 index) const
 
float GetFloatValue (uint16 index) const
 
uint8 GetByteValue (uint16 index, uint8 offset) const
 
uint16 GetUInt16Value (uint16 index, uint8 offset) const
 
ObjectGuid GetGuidValue (uint16 index) const
 
void SetInt32Value (uint16 index, int32 value)
 
void SetUInt32Value (uint16 index, uint32 value)
 
void UpdateUInt32Value (uint16 index, uint32 value)
 
void SetUInt64Value (uint16 index, uint64 value)
 
void SetFloatValue (uint16 index, float value)
 
void SetByteValue (uint16 index, uint8 offset, uint8 value)
 
void SetUInt16Value (uint16 index, uint8 offset, uint16 value)
 
void SetInt16Value (uint16 index, uint8 offset, int16 value)
 
void SetGuidValue (uint16 index, ObjectGuid value)
 
void SetStatFloatValue (uint16 index, float value)
 
void SetStatInt32Value (uint16 index, int32 value)
 
bool AddGuidValue (uint16 index, ObjectGuid value)
 
bool RemoveGuidValue (uint16 index, ObjectGuid value)
 
void ApplyModUInt32Value (uint16 index, int32 val, bool apply)
 
void ApplyModInt32Value (uint16 index, int32 val, bool apply)
 
void ApplyModUInt64Value (uint16 index, int32 val, bool apply)
 
void ApplyModPositiveFloatValue (uint16 index, float val, bool apply)
 
void ApplyModSignedFloatValue (uint16 index, float val, bool apply)
 
void ApplyPercentModFloatValue (uint16 index, float val, bool apply)
 
void SetFlag (uint16 index, uint32 newFlag)
 
void RemoveFlag (uint16 index, uint32 oldFlag)
 
void ToggleFlag (uint16 index, uint32 flag)
 
bool HasFlag (uint16 index, uint32 flag) const
 
void ApplyModFlag (uint16 index, uint32 flag, bool apply)
 
void SetByteFlag (uint16 index, uint8 offset, uint8 newFlag)
 
void RemoveByteFlag (uint16 index, uint8 offset, uint8 newFlag)
 
bool HasByteFlag (uint16 index, uint8 offset, uint8 flag) const
 
void SetFlag64 (uint16 index, uint64 newFlag)
 
void RemoveFlag64 (uint16 index, uint64 oldFlag)
 
void ToggleFlag64 (uint16 index, uint64 flag)
 
bool HasFlag64 (uint16 index, uint64 flag) const
 
void ApplyModFlag64 (uint16 index, uint64 flag, bool apply)
 
void ClearUpdateMask (bool remove)
 
uint16 GetValuesCount () const
 
virtual bool hasQuest (uint32) const
 
virtual bool hasInvolvedQuest (uint32) const
 
virtual void BuildUpdate (UpdateDataMapType &, UpdatePlayerSet &)
 
void BuildFieldsUpdate (Player *, UpdateDataMapType &) const
 
void SetFieldNotifyFlag (uint16 flag)
 
void RemoveFieldNotifyFlag (uint16 flag)
 
void ForceValuesUpdateAtIndex (uint32)
 
bool IsPlayer () const
 
PlayerToPlayer ()
 
Player const * ToPlayer () const
 
CreatureToCreature ()
 
Creature const * ToCreature () const
 
UnitToUnit ()
 
Unit const * ToUnit () const
 
GameObjectToGameObject ()
 
GameObject const * ToGameObject () const
 
CorpseToCorpse ()
 
Corpse const * ToCorpse () const
 
DynamicObjectToDynObject ()
 
DynamicObject const * ToDynObject () const
 
virtual std::string GetDebugInfo () const
 
- Public Member Functions inherited from WorldLocation
 WorldLocation (uint32 _mapId=MAPID_INVALID, float x=0.f, float y=0.f, float z=0.f, float o=0.f)
 
 WorldLocation (uint32 mapId, Position const &position)
 
void WorldRelocate (const WorldLocation &loc)
 
void WorldRelocate (uint32 mapId=MAPID_INVALID, float x=0.f, float y=0.f, float z=0.f, float o=0.f)
 
void SetMapId (uint32 mapId)
 
uint32 GetMapId () const
 
void GetWorldLocation (uint32 &mapId, float &x, float &y) const
 
void GetWorldLocation (uint32 &mapId, float &x, float &y, float &z) const
 
void GetWorldLocation (uint32 &mapId, float &x, float &y, float &z, float &o) const
 
void GetWorldLocation (WorldLocation *location) const
 
WorldLocation GetWorldLocation () const
 
std::string GetDebugInfo () const
 
- Public Member Functions inherited from Position
 Position (float x=0, float y=0, float z=0, float o=0)
 
 Position (Position const &loc)
 
 Position (Position &&)=default
 
Positionoperator= (const Position &)=default
 
Positionoperator= (Position &&)=default
 
bool operator== (Position const &a) const
 
bool operator!= (Position const &a)
 
 operator G3D::Vector3 () const
 
void Relocate (float x, float y)
 
void Relocate (float x, float y, float z)
 
void Relocate (float x, float y, float z, float orientation)
 
void Relocate (const Position &pos)
 
void Relocate (const Position *pos)
 
void RelocatePolarOffset (float angle, float dist, float z=0.0f)
 
void RelocateOffset (const Position &offset)
 
void SetOrientation (float orientation)
 
float GetPositionX () const
 
float GetPositionY () const
 
float GetPositionZ () const
 
float GetOrientation () const
 
void GetPosition (float &x, float &y) const
 
void GetPosition (float &x, float &y, float &z) const
 
void GetPosition (float &x, float &y, float &z, float &o) const
 
Position GetPosition () const
 
Position::PositionXYZStreamer PositionXYZStream ()
 
Position::PositionXYZOStreamer PositionXYZOStream ()
 
bool IsPositionValid () const
 
float GetExactDist2dSq (const float x, const float y) const
 
float GetExactDist2dSq (Position const &pos) const
 
float GetExactDist2dSq (Position const *pos) const
 
float GetExactDist2d (const float x, const float y) const
 
float GetExactDist2d (Position const &pos) const
 
float GetExactDist2d (Position const *pos) const
 
float GetExactDistSq (float x, float y, float z) const
 
float GetExactDistSq (Position const &pos) const
 
float GetExactDistSq (Position const *pos) const
 
float GetExactDist (float x, float y, float z) const
 
float GetExactDist (Position const &pos) const
 
float GetExactDist (Position const *pos) const
 
void GetPositionOffsetTo (const Position &endPos, Position &retOffset) const
 
Position GetPositionWithOffset (Position const &offset) const
 
float GetAngle (const Position *pos) const
 
float GetAngle (float x, float y) const
 
float GetAbsoluteAngle (float x, float y) const
 
float GetAbsoluteAngle (Position const &pos) const
 
float GetAbsoluteAngle (Position const *pos) const
 
float GetRelativeAngle (const Position *pos) const
 
float GetRelativeAngle (float x, float y) const
 
float ToAbsoluteAngle (float relAngle) const
 
void GetSinCos (float x, float y, float &vsin, float &vcos) const
 
bool IsInDist2d (float x, float y, float dist) const
 
bool IsInDist2d (const Position *pos, float dist) const
 
bool IsInDist (float x, float y, float z, float dist) const
 
bool IsInDist (const Position *pos, float dist) const
 
bool IsWithinBox (const Position &center, float xradius, float yradius, float zradius) const
 
bool HasInArc (float arcangle, const Position *pos, float targetRadius=0.0f) const
 
bool HasInLine (Position const *pos, float width) const
 
std::string ToString () const
 

Static Public Member Functions

static float GetEffectiveResistChance (Unit const *owner, SpellSchoolMask schoolMask, Unit const *victim)
 
static void DealDamageMods (Unit const *victim, uint32 &damage, uint32 *absorb)
 
static uint32 DealDamage (Unit *attacker, Unit *victim, uint32 damage, CleanDamage const *cleanDamage=nullptr, DamageEffectType damagetype=DIRECT_DAMAGE, SpellSchoolMask damageSchoolMask=SPELL_SCHOOL_MASK_NORMAL, SpellInfo const *spellProto=nullptr, bool durabilityLoss=true, bool allowGM=false, Spell const *spell=nullptr)
 
static void Kill (Unit *killer, Unit *victim, bool durabilityLoss=true, WeaponAttackType attackType=BASE_ATTACK, SpellInfo const *spellProto=nullptr, Spell const *spell=nullptr)
 
static int32 DealHeal (Unit *healer, Unit *victim, uint32 addhealth)
 
static void ProcDamageAndSpell (Unit *actor, Unit *victim, uint32 procAttacker, uint32 procVictim, uint32 procEx, uint32 amount, WeaponAttackType attType=BASE_ATTACK, SpellInfo const *procSpellInfo=nullptr, SpellInfo const *procAura=nullptr, int8 procAuraEffectIndex=-1, Spell const *procSpell=nullptr, DamageInfo *damageInfo=nullptr, HealInfo *healInfo=nullptr, uint32 procPhase=2)
 
static void ApplyResilience (Unit const *victim, float *crit, int32 *damage, bool isCrit, CombatRating type)
 
static uint32 SpellCriticalDamageBonus (Unit const *caster, SpellInfo const *spellProto, uint32 damage, Unit const *victim)
 
static uint32 SpellCriticalHealingBonus (Unit const *caster, SpellInfo const *spellProto, uint32 damage, Unit const *victim)
 
static bool IsDamageReducedByArmor (SpellSchoolMask damageSchoolMask, SpellInfo const *spellInfo=nullptr, uint8 effIndex=MAX_SPELL_EFFECTS)
 
static uint32 CalcArmorReducedDamage (Unit const *attacker, Unit const *victim, const uint32 damage, SpellInfo const *spellInfo, uint8 attackerLevel=0, WeaponAttackType attackType=MAX_ATTACK)
 
static void CalcAbsorbResist (DamageInfo &dmgInfo, bool Splited=false)
 
static void CalcHealAbsorb (HealInfo &healInfo)
 
static void HandleSafeUnitPointersOnDelete (Unit *thisUnit)
 
- Static Public Member Functions inherited from Object
static ObjectGuid GetGUID (Object const *o)
 
- Static Public Member Functions inherited from Position
static float NormalizeOrientation (float o)
 

Public Attributes

uint32 m_extraAttacks
 
bool m_canDualWield
 
ControlSet m_Controlled
 
SafeUnitPointer m_movedByPlayer
 
ObjectGuid m_SummonSlot [MAX_SUMMON_SLOT]
 
ObjectGuid m_ObjectSlot [MAX_GAMEOBJECT_SLOT]
 
float m_modMeleeHitChance
 
float m_modRangedHitChance
 
float m_modSpellHitChance
 
int32 m_baseSpellCritChance
 
float m_threatModifier [MAX_SPELL_SCHOOL]
 
float m_modAttackSpeedPct [3]
 
EventProcessor m_Events
 
SpellImmuneList m_spellImmune [MAX_SPELL_IMMUNITY]
 
uint32 m_lastSanctuaryTime
 
PetAuraSet m_petAuras
 
bool IsAIEnabled
 
bool NeedChangeAI
 
bool m_ControlledByPlayer
 
bool m_CreatedByPlayer
 
std::set< SafeUnitPointer * > SafeUnitPointerSet
 
Position m_last_notify_position
 
uint32 m_last_notify_mstime
 
uint16 m_delayed_unit_relocation_timer
 
uint16 m_delayed_unit_ai_notify_timer
 
bool bRequestForcedVisibilityUpdate
 
Movement::MoveSplinemovespline
 
- Public Attributes inherited from WorldObject
FlaggedValuesArray32< int32, uint32, StealthType, TOTAL_STEALTH_TYPESm_stealth
 
FlaggedValuesArray32< int32, uint32, StealthType, TOTAL_STEALTH_TYPESm_stealthDetect
 
FlaggedValuesArray32< int32, uint32, InvisibilityType, TOTAL_INVISIBILITY_TYPESm_invisibility
 
FlaggedValuesArray32< int32, uint32, InvisibilityType, TOTAL_INVISIBILITY_TYPESm_invisibilityDetect
 
FlaggedValuesArray32< int32, uint32, ServerSideVisibilityType, TOTAL_SERVERSIDE_VISIBILITY_TYPESm_serverSideVisibility
 
FlaggedValuesArray32< int32, uint32, ServerSideVisibilityType, TOTAL_SERVERSIDE_VISIBILITY_TYPESm_serverSideVisibilityDetect
 
uint32 LastUsedScriptID
 
MovementInfo m_movementInfo
 
ElunaEventProcessor * elunaEvents
 
- Public Attributes inherited from Object
DataMap CustomData
 
- Public Attributes inherited from WorldLocation
uint32 m_mapId
 
- Public Attributes inherited from Position
float m_positionX = 0
 
float m_positionY = 0
 
float m_positionZ = 0
 
float m_orientation = 0
 

Protected Types

typedef std::list< DynamicObject * > DynObjectList
 
typedef GuidList GameObjectList
 
typedef std::map< ObjectGuid, float > CharmThreatMap
 

Protected Member Functions

 Unit (bool isWorldObject)
 
void BuildValuesUpdate (uint8 updatetype, ByteBuffer *data, Player *target) const override
 
void _UpdateSpells (uint32 time)
 
void _DeleteRemovedAuras ()
 
void _UpdateAutoRepeatSpell ()
 
bool IsAlwaysVisibleFor (WorldObject const *seer) const override
 
bool IsAlwaysDetectableFor (WorldObject const *seer) const override
 
void SetFeared (bool apply)
 
void SetConfused (bool apply)
 
void SetStunned (bool apply)
 
void SetRooted (bool apply, bool isStun=false)
 
- Protected Member Functions inherited from WorldObject
 WorldObject (bool isWorldObject)
 
virtual void ProcessPositionDataChanged (PositionFullTerrainStatus const &data)
 
void SetLocationMapId (uint32 _mapId)
 
void SetLocationInstanceId (uint32 _instanceId)
 
virtual bool IsNeverVisible () const
 
virtual bool IsAlwaysVisibleFor (WorldObject const *) const
 
virtual bool IsInvisibleDueToDespawn () const
 
virtual bool IsAlwaysDetectableFor (WorldObject const *) const
 
- Protected Member Functions inherited from Object
 Object ()
 
void _InitValues ()
 
void _Create (ObjectGuid::LowType guidlow, uint32 entry, HighGuid guidhigh)
 
std::string _ConcatFields (uint16 startIndex, uint16 size) const
 
bool _LoadIntoDataField (std::string const &data, uint32 startOffset, uint32 count)
 
uint32 GetUpdateFieldData (Player const *target, uint32 *&flags) const
 
void BuildMovementUpdate (ByteBuffer *data, uint16 flags) const
 
virtual void BuildValuesUpdate (uint8 updatetype, ByteBuffer *data, Player *target) const
 
virtual void AddToObjectUpdate ()=0
 
virtual void RemoveFromObjectUpdate ()=0
 
void AddToObjectUpdateIfNeeded ()
 

Protected Attributes

UnitAIi_AI
 
UnitAIi_disabledAI
 
uint8 m_realRace
 
uint8 m_race
 
bool m_AutoRepeatFirstCast
 
int32 m_attackTimer [MAX_ATTACK]
 
float m_createStats [MAX_STATS]
 
AttackerSet m_attackers
 
Unitm_attacking
 
DeathState m_deathState
 
int32 m_procDeep
 
DynObjectList m_dynObj
 
GameObjectList m_gameObj
 
uint32 m_transform
 
Spellm_currentSpells [CURRENT_MAX_SPELL]
 
AuraMap m_ownedAuras
 
AuraApplicationMap m_appliedAuras
 
AuraList m_removedAuras
 
AuraMap::iterator m_auraUpdateIterator
 
uint32 m_removedAurasCount
 
AuraEffectList m_modAuras [TOTAL_AURAS]
 
AuraList m_scAuras
 
AuraApplicationList m_interruptableAuras
 
AuraStateAurasMap m_auraStateAuras
 
uint32 m_interruptMask
 
float m_auraModifiersGroup [UNIT_MOD_END][MODIFIER_TYPE_END]
 
float m_weaponDamage [MAX_ATTACK][MAX_WEAPON_DAMAGE_RANGE][MAX_ITEM_PROTO_DAMAGES]
 
bool m_canModifyStats
 
VisibleAuraMap m_visibleAuras
 
float m_speed_rate [MAX_MOVE_TYPE]
 
CharmInfom_charmInfo
 
SharedVisionList m_sharedVision
 
MotionMasteri_motionMaster
 
uint32 m_reactiveTimer [MAX_REACTIVE]
 
int32 m_regenTimer
 
ThreatMgr m_ThreatMgr
 
CharmThreatMap _charmThreatInfo
 
Vehiclem_vehicle
 
Vehiclem_vehicleKit
 
uint32 m_unitTypeMask
 
LiquidTypeEntry const * _lastLiquid
 
bool m_applyResilience
 
bool _instantCast
 
uint32 m_rootTimes
 
- Protected Attributes inherited from WorldObject
std::string m_name
 
bool m_isActive
 
bool m_isFarVisible
 
Optional< float > m_visibilityDistanceOverride
 
const bool m_isWorldObject
 
ZoneScriptm_zoneScript
 
uint32 _zoneId
 
uint32 _areaId
 
float _floorZ
 
bool _outdoors
 
LiquidData _liquidData
 
bool _updatePositionData
 
Transportm_transport
 
- Protected Attributes inherited from Object
uint16 m_objectType
 
TypeID m_objectTypeId
 
uint16 m_updateFlag
 
union {
   int32 *   m_int32Values
 
   uint32 *   m_uint32Values
 
   float *   m_floatValues
 
}; 
 
UpdateMask _changesMask
 
uint16 m_valuesCount
 
uint16 _fieldNotifyFlags
 
bool m_objectUpdated
 

Private Member Functions

bool IsTriggeredAtSpellProcEvent (Unit *victim, Aura *aura, WeaponAttackType attType, bool isVictim, bool active, SpellProcEventEntry const *&spellProcEvent, ProcEventInfo const &eventInfo)
 
bool HandleDummyAuraProc (Unit *victim, uint32 damage, AuraEffect *triggeredByAura, SpellInfo const *procSpell, uint32 procFlag, uint32 procEx, uint32 cooldown, Spell const *spellProc=nullptr)
 
bool HandleAuraProc (Unit *victim, uint32 damage, Aura *triggeredByAura, SpellInfo const *procSpell, uint32 procFlag, uint32 procEx, uint32 cooldown, bool *handled)
 
bool HandleProcTriggerSpell (Unit *victim, uint32 damage, AuraEffect *triggeredByAura, SpellInfo const *procSpell, uint32 procFlag, uint32 procEx, uint32 cooldown, uint32 procPhase, ProcEventInfo &eventInfo)
 
bool HandleOverrideClassScriptAuraProc (Unit *victim, uint32 damage, AuraEffect *triggeredByAura, SpellInfo const *procSpell, uint32 cooldown)
 
bool HandleAuraRaidProcFromChargeWithValue (AuraEffect *triggeredByAura)
 
bool HandleAuraRaidProcFromCharge (AuraEffect *triggeredByAura)
 
void UpdateSplineMovement (uint32 t_diff)
 
void UpdateSplinePosition ()
 
float GetCombatRatingReduction (CombatRating cr) const
 
uint32 GetCombatRatingDamageReduction (CombatRating cr, float rate, float cap, uint32 damage) const
 
float processDummyAuras (float TakenTotalMod) const
 

Private Attributes

uint32 m_state
 
uint32 m_CombatTimer
 
uint32 m_lastManaUse
 
Diminishing m_Diminishing
 
HostileRefMgr m_HostileRefMgr
 
FollowerRefMgr m_FollowingRefMgr
 
Unitm_comboTarget
 
int8 m_comboPoints
 
std::unordered_set< Unit * > m_ComboPointHolders
 
RedirectThreatInfo _redirectThreatInfo
 
bool m_cleanupDone
 
bool m_duringRemoveFromWorld
 
uint32 _oldFactionId
 faction before charm More...
 
bool _isWalkingBeforeCharm
 Are we walking before we were charmed? More...
 
uint32 _lastExtraAttackSpell
 
std::unordered_map< ObjectGuid, uint32extraAttacksTargets
 
ObjectGuid _lastDamagedTargetGuid
 

Detailed Description

Member Typedef Documentation

◆ AttackerSet

typedef std::unordered_set<Unit*> Unit::AttackerSet

◆ AuraApplicationList

◆ AuraApplicationMap

◆ AuraApplicationMapBounds

typedef std::pair<AuraApplicationMap::const_iterator, AuraApplicationMap::const_iterator> Unit::AuraApplicationMapBounds

◆ AuraApplicationMapBoundsNonConst

typedef std::pair<AuraApplicationMap::iterator, AuraApplicationMap::iterator> Unit::AuraApplicationMapBoundsNonConst

◆ AuraEffectList

typedef std::list<AuraEffect*> Unit::AuraEffectList

◆ AuraList

typedef std::list<Aura*> Unit::AuraList

◆ AuraMap

typedef std::multimap<uint32, Aura*> Unit::AuraMap

◆ AuraMapBounds

typedef std::pair<AuraMap::const_iterator, AuraMap::const_iterator> Unit::AuraMapBounds

◆ AuraMapBoundsNonConst

typedef std::pair<AuraMap::iterator, AuraMap::iterator> Unit::AuraMapBoundsNonConst

◆ AuraStateAurasMap

◆ AuraStateAurasMapBounds

typedef std::pair<AuraStateAurasMap::const_iterator, AuraStateAurasMap::const_iterator> Unit::AuraStateAurasMapBounds

◆ CharmThreatMap

typedef std::map<ObjectGuid, float> Unit::CharmThreatMap
protected

◆ ComboPointHolderSet

◆ ControlSet

typedef std::set<Unit*> Unit::ControlSet

◆ Diminishing

◆ DynObjectList

typedef std::list<DynamicObject*> Unit::DynObjectList
protected

◆ GameObjectList

typedef GuidList Unit::GameObjectList
protected

◆ PetAuraSet

typedef std::set<PetAura const*> Unit::PetAuraSet

◆ VisibleAuraMap

Constructor & Destructor Documentation

◆ ~Unit()

Unit::~Unit ( )
override
359{
360 // set current spells as deletable
361 for (uint8 i = 0; i < CURRENT_MAX_SPELL; ++i)
362 if (m_currentSpells[i])
363 {
365 m_currentSpells[i] = nullptr;
366 }
367
369
370 delete i_motionMaster;
371 delete m_charmInfo;
372 delete movespline;
373
376 ASSERT(m_attackers.empty());
377
378 // pussywizard: clear m_sharedVision along with back references
379 if (!m_sharedVision.empty())
380 {
381 do
382 {
383 Player* p = *(m_sharedVision.begin());
384 p->m_isInSharedVisionOf.erase(this);
385 m_sharedVision.remove(p);
386 } while (!m_sharedVision.empty());
387 }
388
389 ASSERT(m_Controlled.empty());
390 ASSERT(m_appliedAuras.empty());
391 ASSERT(m_ownedAuras.empty());
392 ASSERT(m_removedAuras.empty());
393 ASSERT(m_gameObj.empty());
394 ASSERT(m_dynObj.empty());
395
396 if (m_movedByPlayer && m_movedByPlayer != this)
397 LOG_INFO("misc", "Unit::~Unit (A1)");
398
400}
std::uint8_t uint8
Definition: Define.h:110
#define ASSERT
Definition: Errors.h:68
#define LOG_INFO(filterType__,...)
Definition: Log.h:167
#define CURRENT_MAX_SPELL
Definition: Unit.h:985
Definition: Player.h:1046
std::set< Unit * > m_isInSharedVisionOf
Definition: Player.h:2283
void SetReferencedFromCurrent(bool yes)
Definition: Spell.h:558
bool m_duringRemoveFromWorld
Definition: Unit.h:2582
Spell * m_currentSpells[CURRENT_MAX_SPELL]
Definition: Unit.h:2494
AuraList m_removedAuras
Definition: Unit.h:2498
ControlSet m_Controlled
Definition: Unit.h:1864
Movement::MoveSpline * movespline
Definition: Unit.h:2435
CharmInfo * m_charmInfo
Definition: Unit.h:2515
MotionMaster * i_motionMaster
Definition: Unit.h:2518
void _DeleteRemovedAuras()
Definition: Unit.cpp:3776
DynObjectList m_dynObj
Definition: Unit.h:2488
SafeUnitPointer m_movedByPlayer
Definition: Unit.h:1885
AttackerSet m_attackers
Definition: Unit.h:2480
Unit * m_attacking
Definition: Unit.h:2481
GameObjectList m_gameObj
Definition: Unit.h:2491
AuraMap m_ownedAuras
Definition: Unit.h:2496
AuraApplicationMap m_appliedAuras
Definition: Unit.h:2497
static void HandleSafeUnitPointersOnDelete(Unit *thisUnit)
Definition: Unit.cpp:4257
SharedVisionList m_sharedVision
Definition: Unit.h:2516

◆ Unit()

Unit::Unit ( bool  isWorldObject)
explicitprotected
205 : WorldObject(isWorldObject),
206 m_movedByPlayer(nullptr),
208 IsAIEnabled(false),
209 NeedChangeAI(false),
211 m_CreatedByPlayer(false),
213 i_AI(nullptr),
214 i_disabledAI(nullptr),
215 m_realRace(0),
216 m_race(0),
218 m_procDeep(0),
220 i_motionMaster(new MotionMaster(this)),
221 m_regenTimer(0),
222 m_ThreatMgr(this),
223 m_vehicle(nullptr),
224 m_vehicleKit(nullptr),
226 m_HostileRefMgr(this),
227 m_comboTarget(nullptr),
229{
230#ifdef _MSC_VER
231#pragma warning(default:4355)
232#endif
235
237
244
245 m_canDualWield = false;
246
247 m_rootTimes = 0;
248
249 m_state = 0;
251
252 for (uint8 i = 0; i < CURRENT_MAX_SPELL; ++i)
253 m_currentSpells[i] = nullptr;
254
255 for (uint8 i = 0; i < MAX_SUMMON_SLOT; ++i)
256 m_SummonSlot[i].Clear();
257
258 for (uint8 i = 0; i < MAX_GAMEOBJECT_SLOT; ++i)
259 m_ObjectSlot[i].Clear();
260
262
263 m_interruptMask = 0;
264 m_transform = 0;
265 m_canModifyStats = false;
266
267 for (uint8 i = 0; i < MAX_SPELL_IMMUNITY; ++i)
268 m_spellImmune[i].clear();
269
270 for (uint8 i = 0; i < UNIT_MOD_END; ++i)
271 {
276 }
277 // implement 50% base damage from offhand
279
280 for (uint8 i = 0; i < MAX_ATTACK; ++i)
281 {
284
285 m_weaponDamage[i][MINDAMAGE][1] = 0.f;
286 m_weaponDamage[i][MAXDAMAGE][1] = 0.f;
287 }
288
289 for (uint8 i = 0; i < MAX_STATS; ++i)
290 m_createStats[i] = 0.0f;
291
292 m_attacking = nullptr;
293 m_modMeleeHitChance = 0.0f;
295 m_modSpellHitChance = 0.0f;
297
298 m_CombatTimer = 0;
299 m_lastManaUse = 0;
300
301 for (uint8 i = 0; i < MAX_SPELL_SCHOOL; ++i)
302 m_threatModifier[i] = 1.0f;
303
304 for (uint8 i = 0; i < MAX_MOVE_TYPE; ++i)
305 m_speed_rate[i] = 1.0f;
306
307 m_charmInfo = nullptr;
308
310
311 // remove aurastates allowing special moves
312 for (uint8 i = 0; i < MAX_REACTIVE; ++i)
313 m_reactiveTimer[i] = 0;
314
315 m_cleanupDone = false;
317
319
320 m_last_notify_position.Relocate(-5000.0f, -5000.0f, -5000.0f, 0.0f);
325
326 m_applyResilience = false;
327 _instantCast = false;
328
329 _lastLiquid = nullptr;
330
331 _oldFactionId = 0;
332
333 _isWalkingBeforeCharm = false;
334
336}
@ TYPEID_UNIT
Definition: ObjectGuid.h:37
@ TYPEMASK_UNIT
Definition: ObjectGuid.h:51
@ SERVERSIDE_VISIBILITY_GHOST
Definition: SharedDefines.h:1246
#define MAX_STATS
Definition: SharedDefines.h:237
constexpr auto MAX_SPELL_SCHOOL
Definition: SharedDefines.h:264
@ GHOST_VISIBILITY_ALIVE
Definition: SharedDefines.h:1253
#define MAX_SPELL_IMMUNITY
Definition: SharedDefines.h:1376
@ UNIT_MASK_NONE
Definition: Unit.h:674
@ OFF_ATTACK
Definition: Unit.h:397
@ MAX_ATTACK
Definition: Unit.h:399
@ BASE_ATTACK
Definition: Unit.h:396
@ RANGED_ATTACK
Definition: Unit.h:398
@ MINDAMAGE
Definition: Unit.h:254
@ MAXDAMAGE
Definition: Unit.h:255
@ UNIT_MOD_DAMAGE_OFFHAND
Definition: Unit.h:285
@ UNIT_MOD_END
Definition: Unit.h:287
@ ALIVE
Definition: Unit.h:316
#define MAX_MOVE_TYPE
Definition: Unit.h:389
#define MAX_SUMMON_SLOT
Definition: Unit.h:1215
@ BASE_VALUE
Definition: Unit.h:245
@ TOTAL_VALUE
Definition: Unit.h:247
@ TOTAL_PCT
Definition: Unit.h:248
@ BASE_PCT
Definition: Unit.h:246
#define BASE_MAXDAMAGE
Definition: Unit.h:39
@ MAX_REACTIVE
Definition: Unit.h:1207
#define MAX_GAMEOBJECT_SLOT
Definition: Unit.h:1217
#define BASE_MINDAMAGE
Definition: Unit.h:38
@ UPDATEFLAG_LIVING
Definition: UpdateData.h:44
@ UPDATEFLAG_STATIONARY_POSITION
Definition: UpdateData.h:45
void SetValue(FLAG_TYPE flag, T_VALUES value)
Definition: Object.h:360
Definition: MotionMaster.h:110
Definition: MoveSpline.h:40
uint16 m_objectType
Definition: Object.h:228
uint16 m_updateFlag
Definition: Object.h:231
TypeID m_objectTypeId
Definition: Object.h:230
uint32 m_reactiveTimer[MAX_REACTIVE]
Definition: Unit.h:2520
uint32 m_lastSanctuaryTime
Definition: Unit.h:2134
LiquidTypeEntry const * _lastLiquid
Definition: Unit.h:2531
uint32 m_transform
Definition: Unit.h:2492
uint32 m_CombatTimer
Definition: Unit.h:2565
bool m_canModifyStats
Definition: Unit.h:2510
bool NeedChangeAI
Definition: Unit.h:2345
uint32 m_state
Definition: Unit.h:2564
float m_auraModifiersGroup[UNIT_MOD_END][MODIFIER_TYPE_END]
Definition: Unit.h:2508
int32 m_attackTimer[MAX_ATTACK]
Definition: Unit.h:2476
float m_modAttackSpeedPct[3]
Definition: Unit.h:2088
uint8 m_realRace
Definition: Unit.h:2471
Vehicle * m_vehicle
Definition: Unit.h:2527
uint32 m_rootTimes
Definition: Unit.h:2561
uint8 m_race
Definition: Unit.h:2472
UnitAI * i_AI
Definition: Unit.h:2464
uint32 _lastExtraAttackSpell
Definition: Unit.h:2589
bool _instantCast
Definition: Unit.h:2537
ObjectGuid m_ObjectSlot[MAX_GAMEOBJECT_SLOT]
Definition: Unit.h:2066
RedirectThreatInfo _redirectThreatInfo
Definition: Unit.h:2579
float m_createStats[MAX_STATS]
Definition: Unit.h:2478
float m_modRangedHitChance
Definition: Unit.h:2083
DeathState m_deathState
Definition: Unit.h:2483
uint32 m_unitTypeMask
Definition: Unit.h:2530
uint32 m_removedAurasCount
Definition: Unit.h:2500
ThreatMgr m_ThreatMgr
Definition: Unit.h:2523
Unit * m_comboTarget
Definition: Unit.h:2575
AuraMap::iterator m_auraUpdateIterator
Definition: Unit.h:2499
bool m_AutoRepeatFirstCast
Definition: Unit.h:2474
uint16 m_delayed_unit_ai_notify_timer
Definition: Unit.h:2407
int32 m_regenTimer
Definition: Unit.h:2521
bool bRequestForcedVisibilityUpdate
Definition: Unit.h:2408
bool m_ControlledByPlayer
Definition: Unit.h:2357
uint32 m_last_notify_mstime
Definition: Unit.h:2405
SpellImmuneList m_spellImmune[MAX_SPELL_IMMUNITY]
Definition: Unit.h:2133
int8 m_comboPoints
Definition: Unit.h:2576
uint32 _oldFactionId
faction before charm
Definition: Unit.h:2584
int32 m_baseSpellCritChance
Definition: Unit.h:2085
float m_modMeleeHitChance
Definition: Unit.h:2082
float m_weaponDamage[MAX_ATTACK][MAX_WEAPON_DAMAGE_RANGE][MAX_ITEM_PROTO_DAMAGES]
Definition: Unit.h:2509
Position m_last_notify_position
Definition: Unit.h:2404
Vehicle * m_vehicleKit
Definition: Unit.h:2528
bool IsAIEnabled
Definition: Unit.h:2345
HostileRefMgr m_HostileRefMgr
Definition: Unit.h:2571
bool m_applyResilience
Definition: Unit.h:2534
bool m_canDualWield
Definition: Unit.h:1356
uint32 m_interruptMask
Definition: Unit.h:2506
int32 m_procDeep
Definition: Unit.h:2485
float m_speed_rate[MAX_MOVE_TYPE]
Definition: Unit.h:2513
float m_modSpellHitChance
Definition: Unit.h:2084
UnitAI * i_disabledAI
Definition: Unit.h:2464
ObjectGuid m_SummonSlot[MAX_SUMMON_SLOT]
Definition: Unit.h:2065
bool m_cleanupDone
Definition: Unit.h:2581
bool _isWalkingBeforeCharm
Are we walking before we were charmed?
Definition: Unit.h:2585
bool m_CreatedByPlayer
Definition: Unit.h:2358
uint16 m_delayed_unit_relocation_timer
Definition: Unit.h:2406
float m_threatModifier[MAX_SPELL_SCHOOL]
Definition: Unit.h:2087
uint32 m_lastManaUse
Definition: Unit.h:2566
Definition: Object.h:393
FlaggedValuesArray32< int32, uint32, ServerSideVisibilityType, TOTAL_SERVERSIDE_VISIBILITY_TYPES > m_serverSideVisibility
Definition: Object.h:509
void Relocate(float x, float y)
Definition: Position.h:73
Definition: Unit.h:948

Member Function Documentation

◆ _addAttacker()

void Unit::_addAttacker ( Unit pAttacker)
inline
1359 {
1360 m_attackers.insert(pAttacker);
1361 }

◆ _AddAura()

void Unit::_AddAura ( UnitAura aura,
Unit caster 
)
4343{
4345 m_ownedAuras.insert(AuraMap::value_type(aura->GetId(), aura));
4346
4348
4349 if (aura->IsRemoved())
4350 return;
4351
4353 if (aura->IsSingleTarget())
4354 {
4355 ASSERT((IsInWorld() && !IsDuringRemoveFromWorld()) || (aura->GetCasterGUID() == GetGUID()));
4356 /* @HACK: Player is not in world during loading auras.
4357 * Single target auras are not saved or loaded from database
4358 * but may be created as a result of aura links (player mounts with passengers)
4359 */
4360
4361 // register single target aura
4362 caster->GetSingleCastAuras().push_back(aura);
4363 // remove other single target auras
4364 Unit::AuraList& scAuras = caster->GetSingleCastAuras();
4365 for (Unit::AuraList::iterator itr = scAuras.begin(); itr != scAuras.end();)
4366 {
4367 if ((*itr) != aura &&
4368 (*itr)->IsSingleTargetWith(aura))
4369 {
4370 (*itr)->Remove();
4371 itr = scAuras.begin();
4372 }
4373 else
4374 ++itr;
4375 }
4376 }
4377}
@ SPELL_AURA_CONTROL_VEHICLE
Definition: SpellAuraDefines.h:299
ObjectGuid GetCasterGUID() const
Definition: SpellAuras.h:105
bool IsRemoved() const
Definition: SpellAuras.h:161
uint32 GetId() const
Definition: SpellAuras.cpp:466
bool HasEffectType(AuraType type) const
Definition: SpellAuras.cpp:1236
SpellInfo const * GetSpellInfo() const
Definition: SpellAuras.h:100
void SetIsSingleTarget(bool val)
Definition: SpellAuras.h:166
bool IsSingleTarget() const
Definition: SpellAuras.h:164
bool IsInWorld() const
Definition: Object.h:101
ObjectGuid GetGUID() const
Definition: Object.h:107
bool IsSingleTarget() const
Definition: SpellInfo.cpp:1357
void _RemoveNoStackAurasDueToAura(Aura *aura)
Definition: Unit.cpp:4587
std::list< Aura * > AuraList
Definition: Unit.h:1307
bool IsDuringRemoveFromWorld() const
Definition: Unit.h:2391
AuraList & GetSingleCastAuras()
Definition: Unit.h:1965

◆ _ApplyAllAuraStatMods()

void Unit::_ApplyAllAuraStatMods ( )
5395{
5396 for (AuraApplicationMap::iterator i = m_appliedAuras.begin(); i != m_appliedAuras.end(); ++i)
5397 (*i).second->GetBase()->HandleAllEffects(i->second, AURA_EFFECT_HANDLE_STAT, true);
5398}
@ AURA_EFFECT_HANDLE_STAT
Definition: SpellAuraDefines.h:46

◆ _ApplyAura()

void Unit::_ApplyAura ( AuraApplication aurApp,
uint8  effMask 
)
4434{
4435 Aura* aura = aurApp->GetBase();
4436
4438
4439 if (aurApp->GetRemoveMode())
4440 return;
4441
4442 Unit* caster = aura->GetCaster();
4443
4444 // Update target aura state flag
4445 SpellInfo const* spellInfo = aura->GetSpellInfo();
4446 if (AuraStateType aState = spellInfo->GetAuraState())
4447 {
4448 if (aState != AURA_STATE_CONFLAGRATE)
4449 {
4450 // Sting (hunter's pet ability), Faerie Fire (druid versions)
4451 if (aState == AURA_STATE_FAERIE_FIRE)
4453
4454 ModifyAuraState(aState, true);
4455 }
4456 else if (caster)
4457 {
4459 m_Events.AddEvent(pEvent, m_Events.CalculateTime(700)); // intended 700ms delay before allowing to cast conflagrate
4460 }
4461 }
4462
4463 if (aurApp->GetRemoveMode())
4464 return;
4465
4466 // Sitdown on apply aura req seated
4469
4470 if (aurApp->GetRemoveMode())
4471 return;
4472
4473 aura->HandleAuraSpecificMods(aurApp, caster, true, false);
4474
4475 // apply effects of the aura
4476 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
4477 {
4478 if (effMask & 1 << i && (!aurApp->GetRemoveMode()))
4479 aurApp->_HandleEffect(i, true);
4480 }
4481
4482 sScriptMgr->OnAuraApply(this, aura);
4483}
#define MAX_SPELL_EFFECTS
Definition: DBCStructure.h:1596
#define sScriptMgr
Definition: ScriptMgr.h:2690
AuraStateType
Definition: SharedDefines.h:1260
@ AURA_STATE_FAERIE_FIRE
Definition: SharedDefines.h:1276
@ AURA_STATE_CONFLAGRATE
Definition: SharedDefines.h:1278
@ SPELL_AURA_MOD_STEALTH
Definition: SpellAuraDefines.h:79
@ AURA_INTERRUPT_FLAG_NOT_SEATED
Definition: SpellDefines.h:62
@ UNIT_STAND_STATE_SIT
Definition: Unit.h:54
Unit * GetTarget() const
Definition: SpellAuras.h:61
void _HandleEffect(uint8 effIndex, bool apply)
Definition: SpellAuras.cpp:161
Aura * GetBase() const
Definition: SpellAuras.h:62
AuraRemoveMode GetRemoveMode() const
Definition: SpellAuras.h:73
Definition: SpellAuras.h:87
Unit * GetCaster() const
Definition: SpellAuras.cpp:471
void HandleAuraSpecificMods(AuraApplication const *aurApp, Unit *caster, bool apply, bool onReapply)
Definition: SpellAuras.cpp:1279
Definition: Unit.h:2651
void AddEvent(BasicEvent *Event, uint64 e_time, bool set_addtime=true)
Definition: EventProcessor.cpp:114
uint64 CalculateTime(uint64 t_offset) const
Definition: EventProcessor.cpp:136
static ObjectGuid GetGUID(Object const *o)
Definition: Object.h:106
Definition: SpellInfo.h:314
AuraStateType GetAuraState() const
Definition: SpellInfo.cpp:2042
uint32 AuraInterruptFlags
Definition: SpellInfo.h:351
Definition: Unit.h:1290
void ModifyAuraState(AuraStateType flag, bool apply)
Definition: Unit.cpp:10445
EventProcessor m_Events
Definition: Unit.h:2091
void RemoveAurasByType(AuraType auraType, ObjectGuid casterGUID=ObjectGuid::Empty, Aura *except=nullptr, bool negative=true, bool positive=true)
Definition: Unit.cpp:5013
void SetStandState(uint8 state)
Definition: Unit.cpp:16812
bool IsSitState() const
Definition: Unit.cpp:16797

◆ _ApplyAuraEffect()

void Unit::_ApplyAuraEffect ( Aura aura,
uint8  effIndex 
)
4420{
4421 ASSERT(aura);
4422 ASSERT(aura->HasEffect(effIndex));
4424 ASSERT(aurApp);
4425 if (!aurApp->GetEffectMask())
4426 _ApplyAura(aurApp, 1 << effIndex);
4427 else
4428 aurApp->_HandleEffect(effIndex, true);
4429}
Definition: SpellAuras.h:37
uint8 GetEffectMask() const
Definition: SpellAuras.h:66
bool HasEffect(uint8 effIndex) const
Definition: SpellAuras.h:173
const AuraApplication * GetApplicationOfTarget(ObjectGuid guid) const
Definition: SpellAuras.h:183
void _ApplyAura(AuraApplication *aurApp, uint8 effMask)
Definition: Unit.cpp:4433

◆ _CreateAuraApplication()

AuraApplication * Unit::_CreateAuraApplication ( Aura aura,
uint8  effMask 
)
4382{
4383 // can't apply aura on unit which is going to be deleted - to not create a memory leak
4385 // aura musn't be removed
4386 ASSERT(!aura->IsRemoved());
4387
4388 // aura mustn't be already applied on target
4389 ASSERT (!aura->IsAppliedOnTarget(GetGUID()) && "Unit::_CreateAuraApplication: aura musn't be applied on target");
4390
4391 SpellInfo const* aurSpellInfo = aura->GetSpellInfo();
4392 uint32 aurId = aurSpellInfo->Id;
4393
4394 // ghost spell check, allow apply any auras at player loading in ghost mode (will be cleanup after load)
4395 // Xinef: Added IsAllowingDeadTarget check
4396 if (!IsAlive() && !aurSpellInfo->IsDeathPersistent() && !aurSpellInfo->IsAllowingDeadTarget() && (GetTypeId() != TYPEID_PLAYER || !ToPlayer()->GetSession()->PlayerLoading()))
4397 return nullptr;
4398
4399 Unit* caster = aura->GetCaster();
4400
4401 AuraApplication* aurApp = new AuraApplication(this, caster, aura, effMask);
4402 m_appliedAuras.insert(AuraApplicationMap::value_type(aurId, aurApp));
4403
4404 // xinef: do not insert our application to interruptible list if application target is not the owner (area auras)
4405 // xinef: even if it gets removed, it will be reapplied in a second
4406 if (aurSpellInfo->AuraInterruptFlags && this == aura->GetOwner())
4407 {
4408 m_interruptableAuras.push_back(aurApp);
4409 AddInterruptMask(aurSpellInfo->AuraInterruptFlags);
4410 }
4411
4412 if (AuraStateType aState = aura->GetSpellInfo()->GetAuraState())
4413 m_auraStateAuras.insert(AuraStateAurasMap::value_type(aState, aurApp));
4414
4415 aura->_ApplyForTarget(this, caster, aurApp);
4416 return aurApp;
4417}
std::uint32_t uint32
Definition: Define.h:108
@ TYPEID_PLAYER
Definition: ObjectGuid.h:38
WorldObject * GetOwner() const
Definition: SpellAuras.h:107
bool IsAppliedOnTarget(ObjectGuid guid) const
Definition: SpellAuras.h:185
virtual void _ApplyForTarget(Unit *target, Unit *caster, AuraApplication *auraApp)
Definition: SpellAuras.cpp:492
Player * ToPlayer()
Definition: Object.h:195
TypeID GetTypeId() const
Definition: Object.h:121
bool IsDeathPersistent() const
Definition: SpellInfo.cpp:1200
uint32 Id
Definition: SpellInfo.h:318
bool IsAllowingDeadTarget() const
Definition: SpellInfo.cpp:1210
void AddInterruptMask(uint32 mask)
Definition: Unit.h:2160
bool IsAlive() const
Definition: Unit.h:1805
AuraApplicationList m_interruptableAuras
Definition: Unit.h:2504
AuraStateAurasMap m_auraStateAuras
Definition: Unit.h:2505

◆ _DeleteRemovedAuras()

void Unit::_DeleteRemovedAuras ( )
protected
3777{
3778 while (!m_removedAuras.empty())
3779 {
3780 delete m_removedAuras.front();
3781 m_removedAuras.pop_front();
3782 }
3783}

◆ _EnterVehicle()

void Unit::_EnterVehicle ( Vehicle vehicle,
int8  seatId,
AuraApplication const *  aurApp = nullptr 
)
19668{
19669 // Must be called only from aura handler
19670 if (!IsAlive() || GetVehicleKit() == vehicle || vehicle->GetBase()->IsOnVehicle(this))
19671 return;
19672
19673 if (m_vehicle)
19674 {
19675 if (m_vehicle == vehicle)
19676 {
19677 if (seatId >= 0 && seatId != GetTransSeat())
19678 {
19679 LOG_DEBUG("vehicles", "EnterVehicle: {} leave vehicle {} seat {} and enter {}.", GetEntry(), m_vehicle->GetBase()->GetEntry(), GetTransSeat(), seatId);
19680 ChangeSeat(seatId);
19681 }
19682
19683 return;
19684 }
19685 else
19686 {
19687 LOG_DEBUG("vehicles", "EnterVehicle: {} exit {} and enter {}.", GetEntry(), m_vehicle->GetBase()->GetEntry(), vehicle->GetBase()->GetEntry());
19688 ExitVehicle();
19689 }
19690 }
19691
19692 if (!aurApp || aurApp->GetRemoveMode())
19693 return;
19694
19695 if (Player* player = ToPlayer())
19696 {
19697 if (vehicle->GetBase()->GetTypeId() == TYPEID_PLAYER && player->IsInCombat())
19698 return;
19699
19700 sScriptMgr->AnticheatSetUnderACKmount(player);
19701 sScriptMgr->AnticheatSetSkipOnePacketForASH(player, true);
19702
19704 player->StopCastingCharm();
19705 player->StopCastingBindSight();
19706 Dismount();
19708
19709 // drop flag at invisible in bg
19710 if (Battleground* bg = player->GetBattleground())
19711 bg->EventPlayerDroppedFlag(player);
19712
19714 player->GetSession()->SendPacket(&data);
19715 }
19716
19717 ASSERT(!m_vehicle);
19718 m_vehicle = vehicle;
19719
19720 if (!m_vehicle->AddPassenger(this, seatId))
19721 {
19722 m_vehicle = nullptr;
19723 return;
19724 }
19725
19726 // Xinef: remove movement auras when entering vehicle (food buffs etc)
19728}
#define LOG_DEBUG(filterType__,...)
Definition: Log.h:171
@ SPELL_AURA_MOUNTED
Definition: SpellAuraDefines.h:141
@ AURA_INTERRUPT_FLAG_MOVE
Definition: SpellDefines.h:47
@ AURA_INTERRUPT_FLAG_TURNING
Definition: SpellDefines.h:48
Definition: Battleground.h:293
uint32 GetEntry() const
Definition: Object.h:109
void InterruptNonMeleeSpells(bool withDelayed, uint32 spellid=0, bool withInstant=true, bool bySelf=false)
Definition: Unit.cpp:4057
void Dismount()
Definition: Unit.cpp:13428
bool IsOnVehicle(Unit const *vehicle) const
Definition: Unit.h:2350
void ChangeSeat(int8 seatId, bool next=true)
Definition: Unit.cpp:19730
Vehicle * GetVehicleKit() const
Definition: Unit.h:2348
void RemoveAurasWithInterruptFlags(uint32 flag, uint32 except=0, bool isAutoshot=false)
Definition: Unit.cpp:5084
void ExitVehicle(Position const *exitPosition=nullptr)
Definition: Unit.cpp:19749
Unit * GetBase() const
May be called from scripts.
Definition: Vehicle.h:39
bool AddPassenger(Unit *passenger, int8 seatId=-1)
Definition: Vehicle.cpp:307
int8 GetTransSeat() const
Definition: Object.h:591
Definition: WorldPacket.h:27
@ SMSG_ON_CANCEL_EXPECTED_RIDE_VEHICLE_AURA
Definition: Opcodes.h:1211

◆ _ExitVehicle()

void Unit::_ExitVehicle ( Position const *  exitPosition = nullptr)
19788{
19789 if (!m_vehicle)
19790 return;
19791
19793
19794 Player* player = ToPlayer();
19795
19796 // If player is on mouted duel and exits the mount should immediatly lose the duel
19797 if (player && player->duel && player->duel->IsMounted)
19798 player->DuelComplete(DUEL_FLED);
19799
19800 // This should be done before dismiss, because there may be some aura removal
19801 Vehicle* vehicle = m_vehicle;
19802 Unit* vehicleBase = m_vehicle->GetBase();
19803 m_vehicle = nullptr;
19804
19805 SetControlled(false, UNIT_STATE_ROOT); // SMSG_MOVE_FORCE_UNROOT, ~MOVEMENTFLAG_ROOT
19806
19807 Position pos;
19808 if (!exitPosition) // Exit position not specified
19809 pos = vehicleBase->GetPosition(); // This should use passenger's current position, leaving it as it is now
19810 // because we calculate positions incorrect (sometimes under map)
19811 else
19812 pos = *exitPosition;
19813
19814 // HACK
19815 if (vehicle->GetVehicleInfo()->m_ID == 380) // Kologarn right arm
19816 pos.Relocate(1776.0f, -24.0f, 448.75f, 0.0f);
19817 else if (vehicle->GetVehicleInfo()->m_ID == 91) // Helsman's Ship
19818 pos.Relocate(2802.18f, 7054.91f, -0.6f, 4.67f);
19819 else if (vehicle->GetVehicleInfo()->m_ID == 349) // AT Mounts, dismount to the right
19820 {
19821 float x = pos.GetPositionX() + 2.0f * cos(pos.GetOrientation() - M_PI / 2.0f);
19822 float y = pos.GetPositionY() + 2.0f * std::sin(pos.GetOrientation() - M_PI / 2.0f);
19823 float z = GetMapHeight(x, y, pos.GetPositionZ());
19824 if (z > INVALID_HEIGHT)
19825 pos.Relocate(x, y, z);
19826 }
19827
19829
19830 if (player)
19831 {
19833
19834 sScriptMgr->AnticheatSetUnderACKmount(player);
19835 sScriptMgr->AnticheatSetSkipOnePacketForASH(player, true);
19836 }
19838 {
19840 data << GetPackGUID();
19841 SendMessageToSet(&data, false);
19842 }
19843
19844 // xinef: hack for flameleviathan seat vehicle
19845 if (vehicle->GetVehicleInfo()->m_ID != 341)
19846 {
19847 Movement::MoveSplineInit init(this);
19848 init.MoveTo(pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ());
19849 init.SetFacing(GetOrientation());
19850 init.SetTransportExit();
19851 init.Launch();
19852 }
19853 else
19854 {
19855 float o = pos.GetAngle(this);
19856 Movement::MoveSplineInit init(this);
19857 init.MoveTo(pos.GetPositionX() + 8 * cos(o), pos.GetPositionY() + 8 * std::sin(o), pos.GetPositionZ() + 16.0f);
19858 init.SetFacing(GetOrientation());
19859 init.SetTransportExit();
19860 init.Launch();
19861 DisableSpline();
19862 KnockbackFrom(pos.GetPositionX(), pos.GetPositionY(), 10.0f, 20.0f);
19864 }
19865
19866 // xinef: move fall, should we support all creatures that exited vehicle in air? Currently Quest Drag and Drop only, Air Assault quest
19867 if (GetTypeId() == TYPEID_UNIT && !CanFly() &&
19868 (vehicle->GetVehicleInfo()->m_ID == 113 || vehicle->GetVehicleInfo()->m_ID == 8 || vehicle->GetVehicleInfo()->m_ID == 290 || vehicle->GetVehicleInfo()->m_ID == 298))
19870 //GetMotionMaster()->MoveFall(); // Enable this once passenger positions are calculater properly (see above)
19871
19872 if ((!player || !(player->GetDelayedOperations() & DELAYED_VEHICLE_TELEPORT)) && vehicle->GetBase()->HasUnitTypeMask(UNIT_MASK_MINION))
19873 if (((Minion*)vehicleBase)->GetOwner() == this)
19874 {
19875 if (vehicle->GetVehicleInfo()->m_ID != 349)
19876 vehicle->Dismiss();
19877 else if (vehicleBase->GetTypeId() == TYPEID_UNIT)
19878 {
19879 vehicle->Uninstall();
19880 vehicleBase->m_Events.AddEvent(new VehicleDespawnEvent(*vehicleBase, 2000), vehicleBase->m_Events.CalculateTime(2000));
19881 }
19882
19883 // xinef: ugly hack, no appripriate hook later to cast spell
19884 if (player)
19885 {
19886 if (vehicleBase->GetEntry() == NPC_EIDOLON_WATCHER)
19887 player->CastSpell(player, VEHICLE_SPELL_SHADE_CONTROL_END, true);
19888 else if (vehicleBase->GetEntry() == NPC_LITHE_STALKER)
19889 player->CastSpell(player, VEHICLE_SPELL_GEIST_CONTROL_END, true);
19890 }
19891 }
19892
19894 {
19895 // Vehicle just died, we die too
19896 if (vehicleBase->getDeathState() == JUST_DIED)
19898 // If for other reason we as minion are exiting the vehicle (ejected, master dismounted) - unsummon
19899 else
19900 {
19901 SetVisible(false);
19902 ToTempSummon()->UnSummon(2000); // Approximation
19903 }
19904 }
19905
19906 if (player)
19908}
#define INVALID_HEIGHT
Definition: Map.h:164
@ DELAYED_VEHICLE_TELEPORT
Definition: Player.h:901
@ DUEL_FLED
Definition: SharedDefines.h:3586
@ MOVEMENTFLAG_ROOT
Definition: Unit.h:563
@ UNIT_MASK_ACCESSORY
Definition: Unit.h:684
@ UNIT_MASK_MINION
Definition: Unit.h:676
@ JUST_DIED
Definition: Unit.h:317
@ UNIT_STATE_ROOT
Definition: Unit.h:335
@ UNIT_STATE_MOVE
Definition: Unit.h:344
@ VEHICLE_SPELL_PARACHUTE
Definition: VehicleDefines.h:54
@ VEHICLE_SPELL_SHADE_CONTROL_END
Definition: VehicleDefines.h:57
@ VEHICLE_SPELL_GEIST_CONTROL_END
Definition: VehicleDefines.h:56
@ NPC_EIDOLON_WATCHER
Definition: VehicleDefines.h:62
@ NPC_LITHE_STALKER
Definition: VehicleDefines.h:63
Definition: TemporarySummon.h:71
void MoveFall(uint32 id=0, bool addFlagForNPC=false)
Definition: MotionMaster.cpp:545
Definition: MoveSplineInit.h:71
PackedGuid const & GetPackGUID() const
Definition: Object.h:108
void DuelComplete(DuelCompleteType type)
Definition: Player.cpp:6293
void SetFallInformation(uint32 time, float z)
Definition: Player.h:2284
std::unique_ptr< DuelInfo > duel
Definition: Player.h:1827
void ResummonPetTemporaryUnSummonedIfAny()
Definition: Player.cpp:13923
uint32 GetDelayedOperations() const
Definition: Player.h:2048
virtual void UnSummon(uint32 msTime=0)
Definition: TemporarySummon.cpp:270
void SetVisible(bool x)
Definition: Unit.cpp:14117
virtual void setDeathState(DeathState s, bool despawn=false)
Definition: Unit.cpp:14425
Unit * GetOwner() const
Definition: Unit.cpp:10548
void SetControlled(bool apply, UnitState state)
Definition: Unit.cpp:18071
DeathState getDeathState()
Definition: Unit.h:1808
virtual bool CanFly() const =0
MotionMaster * GetMotionMaster()
Definition: Unit.h:2257
TempSummon * ToTempSummon()
Definition: Unit.h:2395
void DisableSpline()
Definition: Unit.cpp:654
void AddUnitState(uint32 f)
Definition: Unit.h:1397
bool HasUnitMovementFlag(uint32 f) const
Definition: Unit.h:2269
SpellCastResult CastSpell(SpellCastTargets const &targets, SpellInfo const *spellInfo, CustomSpellValues const *value, TriggerCastFlags triggerFlags=TRIGGERED_NONE, Item *castItem=nullptr, AuraEffect const *triggeredByAura=nullptr, ObjectGuid originalCaster=ObjectGuid::Empty)
Definition: Unit.cpp:1168
uint32 HasUnitTypeMask(uint32 mask) const
Definition: Unit.h:1407
void KnockbackFrom(float x, float y, float speedXY, float speedZ)
Definition: Unit.cpp:19175
Definition: Unit.h:2674
Definition: Vehicle.h:30
void Dismiss()
Definition: Vehicle.cpp:526
VehicleEntry const * GetVehicleInfo() const
Definition: Vehicle.h:40
void RemovePassenger(Unit *passenger)
Definition: Vehicle.cpp:447
void Uninstall()
Definition: Vehicle.cpp:99
float GetMapHeight(float x, float y, float z, bool vmap=true, float distanceToSearch=50.0f) const
Definition: Object.cpp:3032
virtual void SendMessageToSet(WorldPacket const *data, bool self) const
Definition: Object.h:482
@ SMSG_SPLINE_MOVE_UNROOT
Definition: Opcodes.h:802
Seconds GetGameTime()
Definition: GameTime.cpp:38
Definition: Position.h:28
float GetPositionZ() const
Definition: Position.h:119
float GetOrientation() const
Definition: Position.h:120
float GetPositionX() const
Definition: Position.h:117
void GetPosition(float &x, float &y) const
Definition: Position.h:122
float GetPositionY() const
Definition: Position.h:118
float GetAngle(const Position *pos) const
Definition: Position.cpp:77
uint32 m_ID
Definition: DBCStructure.h:1990

◆ _IsNoStackAuraDueToAura()

bool Unit::_IsNoStackAuraDueToAura ( Aura appliedAura,
Aura existingAura 
) const

◆ _IsValidAssistTarget()

bool Unit::_IsValidAssistTarget ( Unit const *  target,
SpellInfo const *  bySpell 
) const
13891{
13892 ASSERT(target);
13893
13894 // can assist to self
13895 if (this == target)
13896 return true;
13897
13898 // can't assist unattackable units or GMs
13899 if (target->HasUnitState(UNIT_STATE_UNATTACKABLE)
13900 || (target->GetTypeId() == TYPEID_PLAYER && target->ToPlayer()->IsGameMaster()))
13901 return false;
13902
13903 // can't assist own vehicle or passenger
13904 if (m_vehicle)
13905 if (IsOnVehicle(target) || m_vehicle->GetBase()->IsOnVehicle(target))
13906 return false;
13907
13908 // can't assist invisible
13909 if ((!bySpell || !bySpell->HasAttribute(SPELL_ATTR6_IGNORE_PHASE_SHIFT)) && !CanSeeOrDetect(target, bySpell && bySpell->IsAffectingArea()))
13910 return false;
13911
13912 // can't assist dead
13913 if ((!bySpell || !bySpell->IsAllowingDeadTarget()) && !target->IsAlive())
13914 return false;
13915
13916 // can't assist untargetable
13917 if ((!bySpell || !bySpell->HasAttribute(SPELL_ATTR6_CAN_TARGET_UNTARGETABLE))
13918 && target->HasUnitFlag(UNIT_FLAG_NOT_SELECTABLE))
13919 return false;
13920
13921 if (!bySpell || !bySpell->HasAttribute(SPELL_ATTR6_CAN_ASSIST_IMMUNE_PC))
13922 {
13923 // xinef: do not allow to assist non attackable units
13924 if (target->HasUnitFlag(UNIT_FLAG_NON_ATTACKABLE))
13925 return false;
13926
13928 {
13929 if (target->IsImmuneToPC())
13930 return false;
13931 }
13932 else
13933 {
13934 if (target->IsImmuneToNPC())
13935 return false;
13936 }
13937 }
13938
13939 // can't assist non-friendly targets
13940 if (GetReactionTo(target) < REP_NEUTRAL
13941 && target->GetReactionTo(this) < REP_NEUTRAL
13942 && (!ToCreature() || !(ToCreature()->GetCreatureTemplate()->type_flags & CREATURE_TYPE_FLAG_TREAT_AS_RAID_UNIT)))
13943 return false;
13944
13945 // PvP case
13946 if (target->HasUnitFlag(UNIT_FLAG_PLAYER_CONTROLLED))
13947 {
13948 Player const* targetPlayerOwner = target->GetAffectingPlayer();
13950 {
13951 Player const* selfPlayerOwner = GetAffectingPlayer();
13952 if (selfPlayerOwner && targetPlayerOwner)
13953 {
13954 // can't assist player which is dueling someone
13955 if (selfPlayerOwner != targetPlayerOwner
13956 && targetPlayerOwner->duel)
13957 return false;
13958 }
13959 // can't assist player in ffa_pvp zone from outside
13960 if (target->IsFFAPvP() && !IsFFAPvP())
13961 return false;
13962
13963 // can't assist player out of sanctuary from sanctuary if has pvp enabled
13964 if (target->IsPvP())
13965 if (IsInSanctuary() && !target->IsInSanctuary())
13966 return false;
13967 }
13968 }
13969 // PvC case - player can assist creature only if has specific type flags
13970 // !target->HasUnitFlag(UNIT_FLAG_PLAYER_CONTROLLED) &&
13972 && (!bySpell || !bySpell->HasAttribute(SPELL_ATTR6_CAN_ASSIST_IMMUNE_PC))
13973 && !target->IsPvP())
13974 {
13975 if (Creature const* creatureTarget = target->ToCreature())
13976 return creatureTarget->GetCreatureTemplate()->type_flags & CREATURE_TYPE_FLAG_TREAT_AS_RAID_UNIT || creatureTarget->GetCreatureTemplate()->type_flags & CREATURE_TYPE_FLAG_CAN_ASSIST;
13977 }
13978 return true;
13979}
@ REP_NEUTRAL
Definition: SharedDefines.h:155
@ CREATURE_TYPE_FLAG_TREAT_AS_RAID_UNIT
Definition: SharedDefines.h:2693
@ CREATURE_TYPE_FLAG_CAN_ASSIST
Definition: SharedDefines.h:2679
@ SPELL_ATTR6_CAN_TARGET_UNTARGETABLE
Definition: SharedDefines.h:600
@ SPELL_ATTR6_IGNORE_PHASE_SHIFT
Definition: SharedDefines.h:589
@ SPELL_ATTR6_CAN_ASSIST_IMMUNE_PC
Definition: SharedDefines.h:579
@ UNIT_STATE_UNATTACKABLE
Definition: Unit.h:362
@ UNIT_FLAG_NON_ATTACKABLE
Definition: Unit.h:449
@ UNIT_FLAG_NOT_SELECTABLE
Definition: Unit.h:473
@ UNIT_FLAG_PLAYER_CONTROLLED
Definition: Unit.h:451
Definition: Creature.h:46
Creature * ToCreature()
Definition: Object.h:197
ReputationRank GetReactionTo(Unit const *target, bool checkOriginalFaction=false) const
Definition: Unit.cpp:10025
bool HasUnitFlag(UnitFlags flags) const
Definition: Unit.h:1478
bool IsInSanctuary() const
Definition: Unit.h:1514
bool IsFFAPvP() const
Definition: Unit.h:1516
Player * GetAffectingPlayer() const
Definition: Unit.cpp:10573
bool CanSeeOrDetect(WorldObject const *obj, bool ignoreStealth=false, bool distanceCheck=false, bool checkAlert=false) const
Definition: Object.cpp:1726

◆ _IsValidAttackTarget()

bool Unit::_IsValidAttackTarget ( Unit const *  target,
SpellInfo const *  bySpell,
WorldObject const *  obj = nullptr 
) const
13771{
13772 ASSERT(target);
13773
13774 // can't attack self
13775 if (this == target)
13776 return false;
13777
13778 // can't attack unattackable units or GMs
13779 if (target->HasUnitState(UNIT_STATE_UNATTACKABLE)
13780 || (target->GetTypeId() == TYPEID_PLAYER && target->ToPlayer()->IsGameMaster()))
13781 return false;
13782
13783 // can't attack own vehicle or passenger
13784 if (m_vehicle)
13785 if (IsOnVehicle(target) || m_vehicle->GetBase()->IsOnVehicle(target))
13786 if (!IsHostileTo(target)) // pussywizard: actually can attack own vehicle or passenger if it's hostile to us - needed for snobold in Gormok encounter
13787 return false;
13788
13789 // can't attack invisible (ignore stealth for aoe spells) also if the area being looked at is from a spell use the dynamic object created instead of the casting unit.
13790 //Ignore stealth if target is player and unit in combat with same player
13791 if ((!bySpell || !bySpell->HasAttribute(SPELL_ATTR6_IGNORE_PHASE_SHIFT)) && (obj ? !obj->CanSeeOrDetect(target, bySpell && bySpell->IsAffectingArea()) : !CanSeeOrDetect(target, (bySpell && bySpell->IsAffectingArea()) || (target->GetTypeId() == TYPEID_PLAYER && target->HasStealthAura() && target->IsInCombat() && IsInCombatWith(target)))))
13792 return false;
13793
13794 // can't attack dead
13795 if ((!bySpell || !bySpell->IsAllowingDeadTarget()) && !target->IsAlive())
13796 return false;
13797
13798 // can't attack untargetable
13799 if ((!bySpell || !bySpell->HasAttribute(SPELL_ATTR6_CAN_TARGET_UNTARGETABLE))
13800 && target->HasUnitFlag(UNIT_FLAG_NOT_SELECTABLE))
13801 return false;
13802
13803 if (Player const* playerAttacker = ToPlayer())
13804 {
13805 if (playerAttacker->HasPlayerFlag(PLAYER_FLAGS_UBER) || playerAttacker->IsSpectator())
13806 return false;
13807 }
13808 // check flags
13810 || (!HasUnitFlag(UNIT_FLAG_PLAYER_CONTROLLED) && target->IsImmuneToNPC())
13811 || (!target->HasUnitFlag(UNIT_FLAG_PLAYER_CONTROLLED) && IsImmuneToNPC())
13812 || (HasUnitFlag(UNIT_FLAG_PLAYER_CONTROLLED) && target->IsImmuneToPC())
13813 // check if this is a world trigger cast - GOs are using world triggers to cast their spells, so we need to ignore their immunity flag here, this is a temp workaround, needs removal when go cast is implemented properly
13814 || ((GetEntry() != WORLD_TRIGGER && (!obj || !obj->isType(TYPEMASK_GAMEOBJECT | TYPEMASK_DYNAMICOBJECT))) && target->HasUnitFlag(UNIT_FLAG_PLAYER_CONTROLLED) && IsImmuneToPC()))
13815 return false;
13816
13817 // CvC case - can attack each other only when one of them is hostile
13819 return GetReactionTo(target) <= REP_HOSTILE || target->GetReactionTo(this) <= REP_HOSTILE;
13820
13821 // PvP, PvC, CvP case
13822 // can't attack friendly targets
13823 ReputationRank repThisToTarget = GetReactionTo(target);
13824 ReputationRank repTargetToThis;
13825
13826 if (repThisToTarget > REP_NEUTRAL
13827 || (repTargetToThis = target->GetReactionTo(this)) > REP_NEUTRAL)
13828 return false;
13829
13830 // Not all neutral creatures can be attacked (even some unfriendly faction does not react aggresive to you, like Sporaggar)
13831 if (repThisToTarget == REP_NEUTRAL &&
13832 repTargetToThis <= REP_NEUTRAL)
13833 {
13834 Player* owner = GetAffectingPlayer();
13835 Unit const* const thisUnit = owner ? owner : this;
13836 if (!(target->GetTypeId() == TYPEID_PLAYER && thisUnit->GetTypeId() == TYPEID_PLAYER) &&
13837 !(target->GetTypeId() == TYPEID_UNIT && thisUnit->GetTypeId() == TYPEID_UNIT))
13838 {
13839 Player const* player = target->GetTypeId() == TYPEID_PLAYER ? target->ToPlayer() : thisUnit->ToPlayer();
13840 Unit const* creature = target->GetTypeId() == TYPEID_UNIT ? target : thisUnit;
13841
13842 if (FactionTemplateEntry const* factionTemplate = creature->GetFactionTemplateEntry())
13843 {
13844 if (!(player->GetReputationMgr().GetForcedRankIfAny(factionTemplate)))
13845 if (FactionEntry const* factionEntry = sFactionStore.LookupEntry(factionTemplate->faction))
13846 if (FactionState const* repState = player->GetReputationMgr().GetState(factionEntry))
13847 if (!(repState->Flags & FACTION_FLAG_AT_WAR))
13848 return false;
13849 }
13850 }
13851 }
13852
13853 Creature const* creatureAttacker = ToCreature();
13854 if (creatureAttacker && creatureAttacker->GetCreatureTemplate()->type_flags & CREATURE_TYPE_FLAG_TREAT_AS_RAID_UNIT)
13855 return false;
13856
13857 Player const* playerAffectingAttacker = HasUnitFlag(UNIT_FLAG_PLAYER_CONTROLLED) ? GetAffectingPlayer() : nullptr;
13858 Player const* playerAffectingTarget = target->HasUnitFlag(UNIT_FLAG_PLAYER_CONTROLLED) ? target->GetAffectingPlayer() : nullptr;
13859
13860 // check duel - before sanctuary checks
13861 if (playerAffectingAttacker && playerAffectingTarget)
13862 if (playerAffectingAttacker->duel && playerAffectingAttacker->duel->Opponent == playerAffectingTarget && playerAffectingAttacker->duel->State == DUEL_STATE_IN_PROGRESS)
13863 return true;
13864
13865 // PvP case - can't attack when attacker or target are in sanctuary
13866 // however, 13850 client doesn't allow to attack when one of the unit's has sanctuary flag and is pvp
13867 if (target->HasUnitFlag(UNIT_FLAG_PLAYER_CONTROLLED) && HasUnitFlag(UNIT_FLAG_PLAYER_CONTROLLED) && (target->IsInSanctuary() || IsInSanctuary()))
13868 return false;
13869
13870 // additional checks - only PvP case
13871 if (playerAffectingAttacker && playerAffectingTarget)
13872 {
13873 if (target->IsPvP())
13874 return true;
13875
13876 if (IsFFAPvP() && target->IsFFAPvP())
13877 return true;
13878
13880 }
13881 return true;
13882}
@ FACTION_FLAG_AT_WAR
Definition: DBCEnums.h:313
DBCStorage< FactionEntry > sFactionStore(FactionEntryfmt)
@ TYPEMASK_DYNAMICOBJECT
Definition: ObjectGuid.h:54
@ TYPEMASK_GAMEOBJECT
Definition: ObjectGuid.h:53
@ DUEL_STATE_IN_PROGRESS
Definition: Player.h:373
@ PLAYER_FLAGS_UBER
Definition: Player.h:494
ReputationRank
Definition: SharedDefines.h:151
@ REP_HOSTILE
Definition: SharedDefines.h:153
#define WORLD_TRIGGER
Definition: Unit.h:36
@ UNIT_BYTE2_FLAG_UNK1
Definition: Unit.h:137
@ UNIT_FLAG_TAXI_FLIGHT
Definition: Unit.h:468
@ UNIT_FLAG_NON_ATTACKABLE_2
Definition: Unit.h:464
@ UNIT_FLAG_NOT_ATTACKABLE_1
Definition: Unit.h:455
@ UNIT_FIELD_BYTES_2
Definition: UpdateFields.h:161
CreatureTemplate const * GetCreatureTemplate() const
Definition: Creature.h:196
bool HasByteFlag(uint16 index, uint8 offset, uint8 flag) const
Definition: Object.cpp:949
ReputationMgr & GetReputationMgr()
Definition: Player.h:2075
FactionState const * GetState(FactionEntry const *factionEntry) const
Definition: ReputationMgr.h:82
ReputationRank const * GetForcedRankIfAny(FactionTemplateEntry const *factionTemplateEntry) const
Definition: ReputationMgr.h:107
FactionTemplateEntry const * GetFactionTemplateEntry() const
Definition: Unit.cpp:9995
bool IsInCombatWith(Unit const *who) const
Definition: Unit.cpp:21042
bool IsImmuneToNPC() const
Definition: Unit.h:1680
bool IsHostileTo(Unit const *unit) const
Definition: Unit.cpp:10197
bool IsImmuneToPC() const
Definition: Unit.h:1678
uint32 type_flags
Definition: CreatureData.h:216
Definition: DBCStructure.h:898
Definition: ReputationMgr.h:42
Definition: DBCStructure.h:930

◆ _RegisterAuraEffect()

void Unit::_RegisterAuraEffect ( AuraEffect aurEff,
bool  apply 
)
4617{
4618 if (apply)
4619 m_modAuras[aurEff->GetAuraType()].push_back(aurEff);
4620 else
4621 m_modAuras[aurEff->GetAuraType()].remove(aurEff);
4622}
AuraType GetAuraType() const
Definition: SpellAuraEffects.cpp:447
AuraEffectList m_modAuras[TOTAL_AURAS]
Definition: Unit.h:2502

◆ _RegisterDynObject()

void Unit::_RegisterDynObject ( DynamicObject dynObj)
6019{
6020 m_dynObj.push_back(dynObj);
6021}

◆ _RemoveAllAuraStatMods()

void Unit::_RemoveAllAuraStatMods ( )
5389{
5390 for (AuraApplicationMap::iterator i = m_appliedAuras.begin(); i != m_appliedAuras.end(); ++i)
5391 (*i).second->GetBase()->HandleAllEffects(i->second, AURA_EFFECT_HANDLE_STAT, false);
5392}

◆ _removeAttacker()

void Unit::_removeAttacker ( Unit pAttacker)
inline
1363 {
1364 m_attackers.erase(pAttacker);
1365 }

◆ _RemoveNoStackAuraApplicationsDueToAura()

void Unit::_RemoveNoStackAuraApplicationsDueToAura ( Aura aura)

◆ _RemoveNoStackAurasDueToAura()

void Unit::_RemoveNoStackAurasDueToAura ( Aura aura)
4588{
4589 //SpellInfo const* spellProto = aura->GetSpellInfo();
4590
4591 // passive spell special case (only non stackable with ranks)
4592
4593 // xinef: this check makes caster to have 2 area auras thanks to spec switch
4594 // if (spellProto->IsPassiveStackableWithRanks())
4595 // return;
4596
4597 bool remove = false;
4598 for (AuraApplicationMap::iterator i = m_appliedAuras.begin(); i != m_appliedAuras.end(); ++i)
4599 {
4600 if (remove)
4601 {
4602 remove = false;
4603 i = m_appliedAuras.begin();
4604 }
4605
4606 if (aura->CanStackWith(i->second->GetBase(), true))
4607 continue;
4608
4610 if (i == m_appliedAuras.end())
4611 break;
4612 remove = true;
4613 }
4614}
@ AURA_REMOVE_BY_DEFAULT
Definition: SpellAuraDefines.h:392
bool CanStackWith(Aura const *checkAura, bool remove) const
Definition: SpellAuras.cpp:2025
void RemoveAura(AuraApplicationMap::iterator &i, AuraRemoveMode mode=AURA_REMOVE_BY_DEFAULT)
Definition: Unit.cpp:4696

◆ _TryStackingOrRefreshingExistingAura()

Aura * Unit::_TryStackingOrRefreshingExistingAura ( SpellInfo const *  newAura,
uint8  effMask,
Unit caster,
int32 baseAmount = nullptr,
Item castItem = nullptr,
ObjectGuid  casterGUID = ObjectGuid::Empty,
bool  periodicReset = false 
)
4283{
4284 ASSERT(casterGUID || caster);
4285 if (!casterGUID)
4286 casterGUID = caster->GetGUID();
4287
4288 // Xinef: Hax for mixology, best solution qq
4289 if (sSpellMgr->GetSpellGroup(newAura->Id) == 1)
4290 return nullptr;
4291
4292 // passive and Incanter's Absorption and auras with different type can stack with themselves any number of times
4293 if (!newAura->IsMultiSlotAura())
4294 {
4295 // check if cast item changed
4296 ObjectGuid castItemGUID;
4297 if (castItem)
4298 castItemGUID = castItem->GetGUID();
4299
4300 // find current aura from spell and change it's stackamount, or refresh it's duration
4301 if (Aura* foundAura = GetOwnedAura(newAura->Id, newAura->HasAttribute(SPELL_ATTR0_CU_SINGLE_AURA_STACK) ? ObjectGuid::Empty : casterGUID, newAura->HasAttribute(SPELL_ATTR0_CU_ENCHANT_PROC) ? castItemGUID : ObjectGuid::Empty, 0))
4302 {
4303 // effect masks do not match
4304 // extremely rare case
4305 // let's just recreate aura
4306 if (effMask != foundAura->GetEffectMask())
4307 return nullptr;
4308
4309 // update basepoints with new values - effect amount will be recalculated in ModStackAmount
4310 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
4311 {
4312 if (!foundAura->HasEffect(i))
4313 continue;
4314
4315 int bp;
4316 if (baseAmount)
4317 bp = *(baseAmount + i);
4318 else
4319 bp = foundAura->GetSpellInfo()->Effects[i].BasePoints;
4320
4321 int32* oldBP = const_cast<int32*>(&(foundAura->GetEffect(i)->m_baseAmount));
4322 *oldBP = bp;
4323 }
4324
4325 // correct cast item guid if needed
4326 if (castItemGUID != foundAura->GetCastItemGUID())
4327 {
4328 ObjectGuid* oldGUID = const_cast<ObjectGuid*>(&foundAura->m_castItemGuid);
4329 *oldGUID = castItemGUID;
4330 }
4331
4332 // try to increase stack amount
4333 foundAura->ModStackAmount(1, AURA_REMOVE_BY_DEFAULT, periodicReset);
4334 sScriptMgr->OnAuraApply(this, foundAura);
4335 return foundAura;
4336 }
4337 }
4338
4339 return nullptr;
4340}
std::int32_t int32
Definition: Define.h:104
@ SPELL_ATTR0_CU_ENCHANT_PROC
Definition: SpellInfo.h:176
@ SPELL_ATTR0_CU_SINGLE_AURA_STACK
Definition: SpellInfo.h:198
#define sSpellMgr
Definition: SpellMgr.h:803
Definition: ObjectGuid.h:120
static ObjectGuid const Empty
Definition: ObjectGuid.h:122
Aura * GetOwnedAura(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, ObjectGuid itemCasterGUID=ObjectGuid::Empty, uint8 reqEffMask=0, Aura *except=nullptr) const
Definition: Unit.cpp:4680

◆ _UnapplyAura() [1/2]

void Unit::_UnapplyAura ( AuraApplication aurApp,
AuraRemoveMode  removeMode 
)
4567{
4568 // aura can be removed from unit only if it's applied on it, shouldn't happen
4569 ASSERT(aurApp->GetBase()->GetApplicationOfTarget(GetGUID()) == aurApp);
4570
4571 uint32 spellId = aurApp->GetBase()->GetId();
4572 AuraApplicationMapBoundsNonConst range = m_appliedAuras.equal_range(spellId);
4573
4574 for (AuraApplicationMap::iterator iter = range.first; iter != range.second;)
4575 {
4576 if (iter->second == aurApp)
4577 {
4578 _UnapplyAura(iter, removeMode);
4579 return;
4580 }
4581 else
4582 ++iter;
4583 }
4584 ABORT();
4585}
#define ABORT
Definition: Errors.h:76
std::pair< AuraApplicationMap::iterator, AuraApplicationMap::iterator > AuraApplicationMapBoundsNonConst
Definition: Unit.h:1301
void _UnapplyAura(AuraApplicationMap::iterator &i, AuraRemoveMode removeMode)
Definition: Unit.cpp:4486

◆ _UnapplyAura() [2/2]

void Unit::_UnapplyAura ( AuraApplicationMap::iterator &  i,
AuraRemoveMode  removeMode 
)
4487{
4488 AuraApplication* aurApp = i->second;
4489 ASSERT(aurApp);
4490 ASSERT(!aurApp->GetRemoveMode());
4491 ASSERT(aurApp->GetTarget() == this);
4492
4493 aurApp->SetRemoveMode(removeMode);
4494 Aura* aura = aurApp->GetBase();
4495 LOG_DEBUG("spells.aura", "Aura {} now is remove mode {}", aura->GetId(), removeMode);
4496
4497 // dead loop is killing the server probably
4498 ASSERT(m_removedAurasCount < 0xFFFFFFFF);
4499
4501
4502 Unit* caster = aura->GetCaster();
4503
4504 // Remove all pointers from lists here to prevent possible pointer invalidation on spellcast/auraapply/auraremove
4505 m_appliedAuras.erase(i);
4506
4507 // xinef: do not insert our application to interruptible list if application target is not the owner (area auras)
4508 // xinef: event if it gets removed, it will be reapplied in a second
4509 if (aura->GetSpellInfo()->AuraInterruptFlags && this == aura->GetOwner())
4510 {
4511 m_interruptableAuras.remove(aurApp);
4513 }
4514
4515 bool auraStateFound = false;
4516 AuraStateType auraState = aura->GetSpellInfo()->GetAuraState();
4517 if (auraState)
4518 {
4519 bool canBreak = false;
4520 // Get mask of all aurastates from remaining auras
4521 for (AuraStateAurasMap::iterator itr = m_auraStateAuras.lower_bound(auraState); itr != m_auraStateAuras.upper_bound(auraState) && !(auraStateFound && canBreak);)
4522 {
4523 if (itr->second == aurApp)
4524 {
4525 m_auraStateAuras.erase(itr);
4526 itr = m_auraStateAuras.lower_bound(auraState);
4527 canBreak = true;
4528 continue;
4529 }
4530 auraStateFound = true;
4531 ++itr;
4532 }
4533 }
4534
4535 aurApp->_Remove();
4536 aura->_UnapplyForTarget(this, caster, aurApp);
4537
4538 // remove effects of the spell - needs to be done after removing aura from lists
4539 for (uint8 itr = 0; itr < MAX_SPELL_EFFECTS; ++itr)
4540 {
4541 if (aurApp->HasEffect(itr))
4542 aurApp->_HandleEffect(itr, false);
4543 }
4544
4545 // all effect mustn't be applied
4546 ASSERT(!aurApp->GetEffectMask());
4547
4548 // Remove totem at next update if totem loses its aura
4549 if (aurApp->GetRemoveMode() == AURA_REMOVE_BY_EXPIRE && IsTotem() && GetGUID() == aura->GetCasterGUID())
4550 {
4551 if (ToTotem()->GetSpell() == aura->GetId() && ToTotem()->GetTotemType() == TOTEM_PASSIVE)
4553 }
4554
4555 // Remove aurastates only if were not found
4556 if (!auraStateFound)
4557 ModifyAuraState(auraState, false);
4558
4559 aura->HandleAuraSpecificMods(aurApp, caster, false, false);
4560
4561 // only way correctly remove all auras from list
4562 //if (removedAuras != m_removedAurasCount) new aura may be added
4563 i = m_appliedAuras.begin();
4564}
@ AURA_REMOVE_BY_EXPIRE
Definition: SpellAuraDefines.h:395
@ TOTEM_PASSIVE
Definition: Totem.h:25
void SetRemoveMode(AuraRemoveMode mode)
Definition: SpellAuras.h:72
void _Remove()
Definition: SpellAuras.cpp:94
bool HasEffect(uint8 effect) const
Definition: SpellAuras.h:67
virtual void _UnapplyForTarget(Unit *target, Unit *caster, AuraApplication *auraApp)
Definition: SpellAuras.cpp:515
void setDeathState(DeathState s, bool despawn=false) override
Definition: TemporarySummon.cpp:375
Totem * ToTotem()
Definition: Unit.h:2394
void UpdateInterruptMask()
Definition: Unit.cpp:758
bool IsTotem() const
Definition: Unit.h:1415

◆ _UnregisterDynObject()

void Unit::_UnregisterDynObject ( DynamicObject dynObj)
6024{
6025 m_dynObj.remove(dynObj);
6026}

◆ _UpdateAutoRepeatSpell()

void Unit::_UpdateAutoRepeatSpell ( )
protected
3842{
3843 SpellInfo const* spellProto = nullptr;
3845 {
3847 }
3848
3849 if (!spellProto)
3850 {
3851 return;
3852 }
3853
3854 static uint32 const HUNTER_AUTOSHOOT = 75;
3855
3856 // Check "realtime" interrupts
3857 if ((GetTypeId() == TYPEID_PLAYER && ToPlayer()->isMoving() && spellProto->Id != HUNTER_AUTOSHOOT) || IsNonMeleeSpellCast(false, false, true, spellProto->Id == HUNTER_AUTOSHOOT))
3858 {
3859 // cancel wand shoot
3860 if (spellProto->Id != HUNTER_AUTOSHOOT)
3862 m_AutoRepeatFirstCast = true;
3863 return;
3864 }
3865
3866 // Apply delay (Hunter's autoshoot not affected)
3867 if (m_AutoRepeatFirstCast && getAttackTimer(RANGED_ATTACK) < 500 && spellProto->Id != HUNTER_AUTOSHOOT)
3868 {
3870 }
3871
3872 m_AutoRepeatFirstCast = false;
3873
3874 // Check for ranged attack timer
3876 {
3878 if (result != SPELL_CAST_OK)
3879 {
3880 if (spellProto->Id != HUNTER_AUTOSHOOT)
3881 {
3883 }
3884
3885 return;
3886 }
3887
3888 // We want to shoot
3889 Spell* spell = new Spell(this, spellProto, TRIGGERED_FULL_MASK);
3890 spell->prepare(&(m_currentSpells[CURRENT_AUTOREPEAT_SPELL]->m_targets));
3891
3892 // Reset attack
3894 }
3895}
SpellCastResult
Definition: SharedDefines.h:920
@ SPELL_CAST_OK
Definition: SharedDefines.h:1110
@ TRIGGERED_FULL_MASK
Will return SPELL_FAILED_DONT_REPORT in CheckCast functions.
Definition: SpellDefines.h:148
@ CURRENT_AUTOREPEAT_SPELL
Definition: Unit.h:981
Definition: Spell.h:284
SpellCastResult prepare(SpellCastTargets const *targets, AuraEffect const *triggeredByAura=nullptr)
Definition: Spell.cpp:3438
SpellCastResult CheckCast(bool strict)
Definition: Spell.cpp:5600
SpellInfo const *const m_spellInfo
Definition: Spell.h:520
void InterruptSpell(CurrentSpellTypes spellType, bool withDelayed=true, bool withInstant=true, bool bySelf=false)
Definition: Unit.cpp:3990
bool IsNonMeleeSpellCast(bool withDelayed, bool skipChanneled=false, bool skipAutorepeat=false, bool isAutoshoot=false, bool skipInstant=true) const
Definition: Unit.cpp:4027
void setAttackTimer(WeaponAttackType type, int32 time)
Definition: Unit.h:1340
bool isMoving() const
Definition: Unit.h:2375
int32 getAttackTimer(WeaponAttackType type) const
Definition: Unit.h:1342
bool isAttackReady(WeaponAttackType type=BASE_ATTACK) const
Definition: Unit.h:1343
void resetAttackTimer(WeaponAttackType type=BASE_ATTACK)
Definition: Unit.cpp:660

◆ _UpdateSpells()

void Unit::_UpdateSpells ( uint32  time)
protected
3786{
3789
3790 // remove finished spells from current pointers
3791 for (uint32 i = 0; i < CURRENT_MAX_SPELL; ++i)
3792 {
3793 if (m_currentSpells[i] && m_currentSpells[i]->getState() == SPELL_STATE_FINISHED)
3794 {
3796 m_currentSpells[i] = nullptr; // remove pointer
3797 }
3798 }
3799
3800 // m_auraUpdateIterator can be updated in indirect called code at aura remove to skip next planned to update but removed auras
3802 {
3803 Aura* i_aura = m_auraUpdateIterator->second;
3804 ++m_auraUpdateIterator; // need shift to next for allow update if need into aura update
3805 i_aura->UpdateOwner(time, this);
3806 }
3807
3808 // remove expired auras - do that after updates(used in scripts?)
3809 for (AuraMap::iterator i = m_ownedAuras.begin(); i != m_ownedAuras.end();)
3810 {
3811 if (i->second->IsExpired())
3813 else
3814 ++i;
3815 }
3816
3817 for (VisibleAuraMap::iterator itr = m_visibleAuras.begin(); itr != m_visibleAuras.end(); ++itr)
3818 if (itr->second->IsNeedClientUpdate())
3819 itr->second->ClientUpdate();
3820
3822
3823 if (!m_gameObj.empty())
3824 {
3825 for (GameObjectList::iterator itr = m_gameObj.begin(); itr != m_gameObj.end();)
3826 {
3827 if (GameObject* go = ObjectAccessor::GetGameObject(*this, *itr))
3828 if (!go->isSpawned())
3829 {
3830 go->SetOwnerGUID(ObjectGuid::Empty);
3831 go->SetRespawnTime(0);
3832 go->Delete();
3833 m_gameObj.erase(itr++);
3834 continue;
3835 }
3836 ++itr;
3837 }
3838 }
3839}
@ SPELL_STATE_FINISHED
Definition: Spell.h:226
void UpdateOwner(uint32 diff, WorldObject *owner)
Definition: SpellAuras.cpp:770
Definition: GameObject.h:813
void RemoveOwnedAura(AuraMap::iterator &i, AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT)
Definition: Unit.cpp:4625
void _UpdateAutoRepeatSpell()
Definition: Unit.cpp:3841
VisibleAuraMap m_visibleAuras
Definition: Unit.h:2511
GameObject * GetGameObject(WorldObject const &u, ObjectGuid const guid)
Definition: ObjectAccessor.cpp:189

◆ AddAura() [1/2]

Aura * Unit::AddAura ( SpellInfo const *  spellInfo,
uint8  effMask,
Unit target 
)
18911{
18912 if (!spellInfo)
18913 return nullptr;
18914
18915 if (target->IsImmunedToSpell(spellInfo))
18916 return nullptr;
18917
18918 for (uint32 i = 0; i < MAX_SPELL_EFFECTS; ++i)
18919 {
18920 if (!(effMask & (1 << i)))
18921 continue;
18922 if (target->IsImmunedToSpellEffect(spellInfo, i))
18923 effMask &= ~(1 << i);
18924 }
18925
18926 if (Aura* aura = Aura::TryRefreshStackOrCreate(spellInfo, effMask, target, this))
18927 {
18928 aura->ApplyForTargets();
18929 return aura;
18930 }
18931 return nullptr;
18932}
static Aura * TryRefreshStackOrCreate(SpellInfo const *spellproto, uint8 tryEffMask, WorldObject *owner, Unit *caster, int32 *baseAmount=nullptr, Item *castItem=nullptr, ObjectGuid casterGUID=ObjectGuid::Empty, bool *refresh=nullptr, bool periodicReset=false)
Definition: SpellAuras.cpp:326
virtual bool IsImmunedToSpellEffect(SpellInfo const *spellInfo, uint32 index) const
Definition: Unit.cpp:12910
virtual bool IsImmunedToSpell(SpellInfo const *spellInfo, Spell const *spell=nullptr)
Definition: Unit.cpp:12820

◆ AddAura() [2/2]

Aura * Unit::AddAura ( uint32  spellId,
Unit target 
)
18896{
18897 if (!target)
18898 return nullptr;
18899
18900 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId);
18901 if (!spellInfo)
18902 return nullptr;
18903
18904 if (!target->IsAlive() && !spellInfo->HasAttribute(SPELL_ATTR0_PASSIVE) && !spellInfo->HasAttribute(SPELL_ATTR2_ALLOW_DEAD_TARGET))
18905 return nullptr;
18906
18907 return AddAura(spellInfo, MAX_EFFECT_MASK, target);
18908}
#define MAX_EFFECT_MASK
Definition: DBCStructure.h:1597
@ SPELL_ATTR2_ALLOW_DEAD_TARGET
Definition: SharedDefines.h:428
@ SPELL_ATTR0_PASSIVE
Definition: SharedDefines.h:360
bool HasAttribute(SpellAttr0 attribute) const
Definition: SpellInfo.h:412
Aura * AddAura(uint32 spellId, Unit *target)
Definition: Unit.cpp:18895

◆ AddComboPointHolder()

void Unit::AddComboPointHolder ( Unit unit)
inline
2294{ m_ComboPointHolders.insert(unit); }
std::unordered_set< Unit * > m_ComboPointHolders
Definition: Unit.h:2577

◆ AddComboPoints() [1/2]

void Unit::AddComboPoints ( int8  count)
inline
2290{ AddComboPoints(nullptr, count); }
void AddComboPoints(Unit *target, int8 count)
Definition: Unit.cpp:16899

◆ AddComboPoints() [2/2]

void Unit::AddComboPoints ( Unit target,
int8  count 
)
16900{
16901 if (!count)
16902 {
16903 return;
16904 }
16905
16906 if (target && target != m_comboTarget)
16907 {
16908 if (m_comboTarget)
16909 {
16911 }
16912
16913 m_comboTarget = target;
16914 m_comboPoints = count;
16915 target->AddComboPointHolder(this);
16916 }
16917 else
16918 {
16919 m_comboPoints = std::max<int8>(std::min<int8>(m_comboPoints + count, 5), 0);
16920 }
16921
16923}
void SendComboPoints()
Definition: Unit.cpp:16942
void AddComboPointHolder(Unit *unit)
Definition: Unit.h:2294
void RemoveComboPointHolder(Unit *unit)
Definition: Unit.h:2295

◆ AddExtraAttacks()

void Unit::AddExtraAttacks ( uint32  count)
2716{
2718 if (!targetGUID)
2719 {
2720 if (ObjectGuid selection = GetTarget())
2721 {
2722 targetGUID = selection; // Spell was cast directly (not triggered by aura)
2723 }
2724 else
2725 return;
2726 }
2727
2728 extraAttacksTargets[targetGUID] += count;
2729}
std::unordered_map< ObjectGuid, uint32 > extraAttacksTargets
Definition: Unit.h:2590
ObjectGuid _lastDamagedTargetGuid
Definition: Unit.h:2591
ObjectGuid GetTarget() const
Definition: Unit.h:2428

◆ AddExtraUnitMovementFlag()

void Unit::AddExtraUnitMovementFlag ( uint16  f)
inline
2273{ m_movementInfo.flags2 |= f; }
MovementInfo m_movementInfo
Definition: Object.h:595
uint16 flags2
Definition: Object.h:268

◆ addFollower()

void Unit::addFollower ( FollowerReference pRef)
inline
void insertFirst(LinkedListElement *pElem)
Definition: LinkedList.h:105
FollowerRefMgr m_FollowingRefMgr
Definition: Unit.h:2573

◆ AddGameObject()

void Unit::AddGameObject ( GameObject gameObj)
6080{
6081 if (!gameObj || gameObj->GetOwnerGUID())
6082 return;
6083
6084 m_gameObj.push_back(gameObj->GetGUID());
6085 gameObj->SetOwnerGUID(GetGUID());
6086
6087 if (GetTypeId() == TYPEID_PLAYER && gameObj->GetSpellId())
6088 {
6089 SpellInfo const* createBySpell = sSpellMgr->GetSpellInfo(gameObj->GetSpellId());
6090 // Need disable spell use for owner
6091 if (createBySpell && createBySpell->IsCooldownStartedOnEvent())
6092 // note: item based cooldowns and cooldown spell mods with charges ignored (unknown existing cases)
6093 ToPlayer()->AddSpellAndCategoryCooldowns(createBySpell, 0, nullptr, true);
6094 }
6095}
uint32 GetSpellId() const
Definition: GameObject.h:874
void SetOwnerGUID(ObjectGuid owner)
Definition: GameObject.h:856
ObjectGuid GetOwnerGUID() const
Definition: GameObject.h:866
void AddSpellAndCategoryCooldowns(SpellInfo const *spellInfo, uint32 itemId, Spell *spell=nullptr, bool infinityCooldown=false)
Definition: Player.cpp:10635
bool IsCooldownStartedOnEvent() const
Definition: SpellInfo.cpp:1195

◆ addHatedBy()

void Unit::addHatedBy ( HostileReference pHostileReference)
inline
2144{ m_HostileRefMgr.insertFirst(pHostileReference); };

◆ AddInterruptMask()

void Unit::AddInterruptMask ( uint32  mask)
inline
2160{ m_interruptMask |= mask; }

◆ AddPetAura()

void Unit::AddPetAura ( PetAura const *  petSpell)
17348{
17349 if (GetTypeId() != TYPEID_PLAYER)
17350 return;
17351
17352 m_petAuras.insert(petSpell);
17353 if (Pet* pet = ToPlayer()->GetPet())
17354 pet->CastPetAura(petSpell);
17355 else if (Unit* charm = GetCharm())
17356 charm->CastPetAura(petSpell);
17357}
Definition: Pet.h:40
Unit * GetCharm() const
Definition: Unit.cpp:10614
PetAuraSet m_petAuras
Definition: Unit.h:2329
Pet * GetPet(WorldObject const &, ObjectGuid const guid)
Definition: ObjectAccessor.cpp:220

◆ AddPlayerToVision()

void Unit::AddPlayerToVision ( Player player)
11118{
11119 if (m_sharedVision.empty())
11120 {
11121 setActive(true);
11122 SetWorldObject(true);
11123 }
11124 m_sharedVision.push_back(player);
11125 player->m_isInSharedVisionOf.insert(this);
11126}
void SetWorldObject(bool apply)
Definition: Object.cpp:1066
void setActive(bool isActiveObject)
Definition: Object.cpp:1085

◆ AddPointedBy()

void Unit::AddPointedBy ( SafeUnitPointer sup)
inline
2400{ SafeUnitPointerSet.insert(sup); }
std::set< SafeUnitPointer * > SafeUnitPointerSet
Definition: Unit.h:2399

◆ AddSpellCooldown()

virtual void Unit::AddSpellCooldown ( uint32  ,
uint32  ,
uint32  ,
bool  needSendToClient = false,
bool  forceSendToSpectator = false 
)
inlinevirtual

Reimplemented in Player, and Creature.

2416 {
2417 // workaround for unused parameters
2418 (void)needSendToClient;
2419 (void)forceSendToSpectator;
2420 }

◆ AddThreat()

void Unit::AddThreat ( Unit victim,
float  fThreat,
SpellSchoolMask  schoolMask = SPELL_SCHOOL_MASK_NORMAL,
SpellInfo const *  threatSpell = nullptr 
)
14524{
14525 // Only mobs can manage threat lists
14527 {
14528 m_ThreatMgr.AddThreat(victim, fThreat, schoolMask, threatSpell);
14529 }
14530}
@ UNIT_STATE_EVADE
Definition: Unit.h:346
void AddThreat(Unit *victim, float threat, SpellSchoolMask schoolMask=SPELL_SCHOOL_MASK_NORMAL, SpellInfo const *threatSpell=nullptr)
Definition: ThreatMgr.cpp:437
bool CanHaveThreatList() const
Definition: Unit.cpp:14484
bool HasUnitState(const uint32 f) const
Definition: Unit.h:1398

◆ AddToWorld()

void Unit::AddToWorld ( )
overridevirtual

Reimplemented from WorldObject.

15526{
15527 if (!IsInWorld())
15528 {
15530 }
15531}
void AddToWorld() override
Definition: Object.cpp:1176

◆ AddUnitMovementFlag()

void Unit::AddUnitMovementFlag ( uint32  f)
inline
2267{ m_movementInfo.flags |= f; }
uint32 flags
Definition: Object.h:267

◆ AddUnitState()

void Unit::AddUnitState ( uint32  f)
inline
1397{ m_state |= f; }

◆ AddUnitTypeMask()

void Unit::AddUnitTypeMask ( uint32  mask)
inline
1408{ m_unitTypeMask |= mask; }

◆ ApplyAttackTimePercentMod()

void Unit::ApplyAttackTimePercentMod ( WeaponAttackType  att,
float  val,
bool  apply 
)
17116{
17117 float remainingTimePct = std::max((float)m_attackTimer[att], 0.0f) / (GetAttackTime(att) * m_modAttackSpeedPct[att]);
17118 if (val > 0)
17119 {
17121 ApplyPercentModFloatValue(static_cast<uint16>(UNIT_FIELD_BASEATTACKTIME) + att, val, !apply);
17122 }
17123 else
17124 {
17126 ApplyPercentModFloatValue(static_cast<uint16>(UNIT_FIELD_BASEATTACKTIME) + att, -val, apply);
17127 }
17128 m_attackTimer[att] = uint32(GetAttackTime(att) * m_modAttackSpeedPct[att] * remainingTimePct);
17129}
std::uint16_t uint16
Definition: Define.h:109
@ UNIT_FIELD_BASEATTACKTIME
Definition: UpdateFields.h:120
void ApplyPercentModFloatVar(float &var, float val, bool apply)
Definition: Util.h:50
void ApplyPercentModFloatValue(uint16 index, float val, bool apply)
Definition: Object.cpp:829
uint32 GetAttackTime(WeaponAttackType att) const
Definition: Unit.h:1467

◆ ApplyCastTimePercentMod()

void Unit::ApplyCastTimePercentMod ( float  val,
bool  apply 
)
17132{
17133 if (val > 0)
17135 else
17137}
@ UNIT_MOD_CAST_SPEED
Definition: UpdateFields.h:137

◆ ApplyDiminishingAura()

void Unit::ApplyDiminishingAura ( DiminishingGroup  group,
bool  apply 
)
14984{
14985 // Checking for existing in the table
14986 for (Diminishing::iterator i = m_Diminishing.begin(); i != m_Diminishing.end(); ++i)
14987 {
14988 if (i->DRGroup != group)
14989 continue;
14990
14991 if (apply)
14992 i->stack += 1;
14993 else if (i->stack)
14994 {
14995 i->stack -= 1;
14996 // Remember time after last aura from group removed
14997 if (i->stack == 0)
14998 i->hitTime = GameTime::GetGameTimeMS().count();
14999 }
15000 break;
15001 }
15002}
Diminishing m_Diminishing
Definition: Unit.h:2569
Milliseconds GetGameTimeMS()
Definition: GameTime.cpp:43

◆ ApplyDiminishingToDuration()

float Unit::ApplyDiminishingToDuration ( DiminishingGroup  group,
int32 duration,
Unit caster,
DiminishingLevels  Level,
int32  limitduration 
)
14905{
14906 // xinef: dont apply diminish to self casts
14907 if (duration == -1 || group == DIMINISHING_NONE)
14908 return 1.0f;
14909
14910 // test pet/charm masters instead pets/charmeds
14911 Unit const* targetOwner = GetOwner();
14912 Unit const* casterOwner = caster->GetOwner();
14913
14914 // Duration of crowd control abilities on pvp target is limited by 10 sec. (2.2.0)
14915 if (limitduration > 0 && duration > limitduration)
14916 {
14917 Unit const* target = targetOwner ? targetOwner : this;
14918 Unit const* source = casterOwner ? casterOwner : caster;
14919
14920 if ((target->GetTypeId() == TYPEID_PLAYER
14922 && source->GetTypeId() == TYPEID_PLAYER)
14923 duration = limitduration;
14924 }
14925
14926 float mod = 1.0f;
14927
14928 if (group == DIMINISHING_TAUNT)
14929 {
14930 if (GetTypeId() == TYPEID_UNIT && (ToCreature()->GetCreatureTemplate()->flags_extra & CREATURE_FLAG_EXTRA_OBEYS_TAUNT_DIMINISHING_RETURNS))
14931 {
14932 DiminishingLevels diminish = Level;
14933 switch (diminish)
14934 {
14936 break;
14938 mod = 0.65f;
14939 break;
14941 mod = 0.4225f;
14942 break;
14944 mod = 0.274625f;
14945 break;
14947 mod = 0.0f;
14948 break;
14949 default:
14950 break;
14951 }
14952 }
14953 }
14954 // Some diminishings applies to mobs too (for example, Stun)
14956 && ((targetOwner ? (targetOwner->GetTypeId() == TYPEID_PLAYER) : (GetTypeId() == TYPEID_PLAYER))
14957 || (GetTypeId() == TYPEID_UNIT && ToCreature()->GetCreatureTemplate()->flags_extra & CREATURE_FLAG_EXTRA_ALL_DIMINISH)))
14959 {
14960 DiminishingLevels diminish = Level;
14961 switch (diminish)
14962 {
14964 break;
14966 mod = 0.5f;
14967 break;
14969 mod = 0.25f;
14970 break;
14972 mod = 0.0f;
14973 break;
14974 default:
14975 break;
14976 }
14977 }
14978
14979 duration = int32(duration * mod);
14980 return mod;
14981}
@ CREATURE_FLAG_EXTRA_OBEYS_TAUNT_DIMINISHING_RETURNS
Definition: CreatureData.h:68
@ CREATURE_FLAG_EXTRA_ALL_DIMINISH
Definition: CreatureData.h:69
@ DIMINISHING_NONE
Definition: SharedDefines.h:3230
@ DIMINISHING_TAUNT
Definition: SharedDefines.h:3248
@ DRTYPE_PLAYER
Definition: SharedDefines.h:3223
@ DRTYPE_ALL
Definition: SharedDefines.h:3224
DiminishingReturnsType GetDiminishingReturnsGroupType(DiminishingGroup group)
Definition: SpellMgr.cpp:246
DiminishingLevels
Definition: Unit.h:693
@ DIMINISHING_LEVEL_3
Definition: Unit.h:696
@ DIMINISHING_LEVEL_1
Definition: Unit.h:694
@ DIMINISHING_LEVEL_4
Definition: Unit.h:698
@ DIMINISHING_LEVEL_IMMUNE
Definition: Unit.h:697
@ DIMINISHING_LEVEL_TAUNT_IMMUNE
Definition: Unit.h:699
@ DIMINISHING_LEVEL_2
Definition: Unit.h:695
uint32 flags_extra
Definition: CreatureData.h:239

◆ ApplyEffectModifiers()

float Unit::ApplyEffectModifiers ( SpellInfo const *  spellProto,
uint8  effect_index,
float  value 
) const
14687{
14688 if (Player* modOwner = GetSpellModOwner())
14689 {
14690 modOwner->ApplySpellMod(spellProto->Id, SPELLMOD_ALL_EFFECTS, value);
14691 switch (effect_index)
14692 {
14693 case 0:
14694 modOwner->ApplySpellMod(spellProto->Id, SPELLMOD_EFFECT1, value);
14695 break;
14696 case 1:
14697 modOwner->ApplySpellMod(spellProto->Id, SPELLMOD_EFFECT2, value);
14698 break;
14699 case 2:
14700 modOwner->ApplySpellMod(spellProto->Id, SPELLMOD_EFFECT3, value);
14701 break;
14702 }
14703 }
14704 return value;
14705}
@ SPELLMOD_EFFECT2
Definition: SpellDefines.h:89
@ SPELLMOD_ALL_EFFECTS
Definition: SpellDefines.h:85
@ SPELLMOD_EFFECT3
Definition: SpellDefines.h:100
@ SPELLMOD_EFFECT1
Definition: SpellDefines.h:80
Player * GetSpellModOwner() const
Definition: Unit.cpp:16681

◆ ApplyResilience()

void Unit::ApplyResilience ( Unit const *  victim,
float *  crit,
int32 damage,
bool  isCrit,
CombatRating  type 
)
static
18960{
18961 // player mounted on multi-passenger mount is also classified as vehicle
18962 if (victim->IsVehicle() && victim->GetTypeId() != TYPEID_PLAYER)
18963 return;
18964
18965 Unit const* target = nullptr;
18966 if (victim->GetTypeId() == TYPEID_PLAYER)
18967 target = victim;
18968 else if (victim->GetTypeId() == TYPEID_UNIT)
18969 {
18970 if (Unit* owner = victim->GetOwner())
18971 if (owner->GetTypeId() == TYPEID_PLAYER)
18972 target = owner;
18973 }
18974
18975 if (!target)
18976 return;
18977
18978 switch (type)
18979 {
18981 // Crit chance reduction works against nonpets
18982 if (crit)
18983 *crit -= target->GetMeleeCritChanceReduction();
18984 if (damage)
18985 {
18986 if (isCrit)
18987 *damage -= target->GetMeleeCritDamageReduction(*damage);
18988 *damage -= target->GetMeleeDamageReduction(*damage);
18989 }
18990 break;
18992 // Crit chance reduction works against nonpets
18993 if (crit)
18994 *crit -= target->GetRangedCritChanceReduction();
18995 if (damage)
18996 {
18997 if (isCrit)
18998 *damage -= target->GetRangedCritDamageReduction(*damage);
18999 *damage -= target->GetRangedDamageReduction(*damage);
19000 }
19001 break;
19003 // Crit chance reduction works against nonpets
19004 if (crit)
19005 *crit -= target->GetSpellCritChanceReduction();
19006 if (damage)
19007 {
19008 if (isCrit)
19009 *damage -= target->GetSpellCritDamageReduction(*damage);
19010 *damage -= target->GetSpellDamageReduction(*damage);
19011 }
19012 break;
19013 default:
19014 break;
19015 }
19016}
@ CR_CRIT_TAKEN_RANGED
Definition: Unit.h:419
@ CR_CRIT_TAKEN_SPELL
Definition: Unit.h:420
@ CR_CRIT_TAKEN_MELEE
Definition: Unit.h:418
float GetSpellCritChanceReduction() const
Definition: Unit.h:1578
float GetRangedCritChanceReduction() const
Definition: Unit.h:1577
uint32 GetSpellCritDamageReduction(uint32 damage) const
Definition: Unit.h:1583
float GetMeleeCritChanceReduction() const
Definition: Unit.h:1576
uint32 GetRangedDamageReduction(uint32 damage) const
Definition: Unit.h:1587
uint32 GetRangedCritDamageReduction(uint32 damage) const
Definition: Unit.h:1582
uint32 GetMeleeCritDamageReduction(uint32 damage) const
Definition: Unit.h:1581
uint32 GetSpellDamageReduction(uint32 damage) const
Definition: Unit.h:1588
uint32 GetMeleeDamageReduction(uint32 damage) const
Definition: Unit.h:1586

◆ ApplyResistanceBuffModsMod()

void Unit::ApplyResistanceBuffModsMod ( SpellSchools  school,
bool  positive,
float  val,
bool  apply 
)
inline
2024{ ApplyModSignedFloatValue(positive ? static_cast<uint16>(UNIT_FIELD_RESISTANCEBUFFMODSPOSITIVE) + school : static_cast<uint16>(UNIT_FIELD_RESISTANCEBUFFMODSNEGATIVE) + + school, val, apply); }
@ UNIT_FIELD_RESISTANCEBUFFMODSPOSITIVE
Definition: UpdateFields.h:157
@ UNIT_FIELD_RESISTANCEBUFFMODSNEGATIVE
Definition: UpdateFields.h:158
void ApplyModSignedFloatValue(uint16 index, float val, bool apply)
Definition: Object.cpp:822

◆ ApplyResistanceBuffModsPercentMod()

void Unit::ApplyResistanceBuffModsPercentMod ( SpellSchools  school,
bool  positive,
float  val,
bool  apply 
)
inline
2025{ ApplyPercentModFloatValue(positive ? static_cast<uint16>(UNIT_FIELD_RESISTANCEBUFFMODSPOSITIVE) + school : static_cast<uint16>(UNIT_FIELD_RESISTANCEBUFFMODSNEGATIVE) + + school, val, apply); }

◆ ApplySpellDispelImmunity()

void Unit::ApplySpellDispelImmunity ( SpellInfo const *  spellProto,
DispelType  type,
bool  apply 
)
13321{
13322 ApplySpellImmune(spellProto->Id, IMMUNITY_DISPEL, type, apply);
13323
13324 if (apply && spellProto->HasAttribute(SPELL_ATTR1_IMMUNITY_PURGES_EFFECT))
13325 {
13326 // Create dispel mask by dispel type
13327 uint32 dispelMask = SpellInfo::GetDispelMask(type);
13328 // Dispel all existing auras vs current dispel type
13330 for (AuraApplicationMap::iterator itr = auras.begin(); itr != auras.end();)
13331 {
13332 SpellInfo const* spell = itr->second->GetBase()->GetSpellInfo();
13333 if (spell->GetDispelMask() & dispelMask)
13334 {
13335 // Dispel aura
13336 RemoveAura(itr);
13337 }
13338 else
13339 ++itr;
13340 }
13341 }
13342}
@ SPELL_ATTR1_IMMUNITY_PURGES_EFFECT
Definition: SharedDefines.h:406
@ IMMUNITY_DISPEL
Definition: SharedDefines.h:1370
uint32 GetDispelMask() const
Definition: SpellInfo.cpp:2023
void ApplySpellImmune(uint32 spellId, uint32 op, uint32 type, bool apply, SpellImmuneBlockType blockType=SPELL_BLOCK_TYPE_ALL)
Definition: Unit.cpp:13293
std::multimap< uint32, AuraApplication * > AuraApplicationMap
Definition: Unit.h:1299
AuraApplicationMap & GetAppliedAuras()
Definition: Unit.h:1921

◆ ApplySpellImmune()

void Unit::ApplySpellImmune ( uint32  spellId,
uint32  op,
uint32  type,
bool  apply,
SpellImmuneBlockType  blockType = SPELL_BLOCK_TYPE_ALL 
)
13294{
13295 if (apply)
13296 {
13297 // xinef: immunities with spellId 0 are intended to be applied only once (script purposes mosty)
13298 if (spellId == 0 && std::find_if(m_spellImmune[op].begin(), m_spellImmune[op].end(), spellIdImmunityPredicate(type)) != m_spellImmune[op].end())
13299 return;
13300
13301 SpellImmune immune;
13302 immune.spellId = spellId;
13303 immune.type = type;
13304 immune.blockType = blockType;
13305 m_spellImmune[op].push_back(std::move(immune));
13306 }
13307 else
13308 {
13309 for (SpellImmuneList::iterator itr = m_spellImmune[op].begin(); itr != m_spellImmune[op].end(); ++itr)
13310 {
13311 if (itr->spellId == spellId && itr->type == type)
13312 {
13313 m_spellImmune[op].erase(itr);
13314 break;
13315 }
13316 }
13317 }
13318}
Definition: Unit.cpp:13284
Definition: SpellDefines.h:171
uint32 blockType
Definition: SpellDefines.h:176
uint32 spellId
Definition: SpellDefines.h:174
uint32 type
Definition: SpellDefines.h:175

◆ ApplyStatBuffMod()

void Unit::ApplyStatBuffMod ( Stats  stat,
float  val,
bool  apply 
)
inline
2031{ ApplyModSignedFloatValue((val > 0 ? static_cast<uint16>(UNIT_FIELD_POSSTAT0) + stat : static_cast<uint16>(UNIT_FIELD_NEGSTAT0) + stat), val, apply); }
@ UNIT_FIELD_POSSTAT0
Definition: UpdateFields.h:146
@ UNIT_FIELD_NEGSTAT0
Definition: UpdateFields.h:151

◆ ApplyStatPercentBuffMod()

void Unit::ApplyStatPercentBuffMod ( Stats  stat,
float  val,
bool  apply 
)
15195{
15196 if (val == -100.0f) // prevent set var to zero
15197 val = -99.99f;
15198 float var = GetStat(stat) * val / 100.0f;
15199 ApplyModSignedFloatValue((var > 0 ? static_cast<uint16>(UNIT_FIELD_POSSTAT0) + stat : static_cast<uint16>(UNIT_FIELD_NEGSTAT0) + stat), var, apply);
15200}
float GetStat(Stats stat) const
Definition: Unit.h:1428

◆ ApplyTotalThreatModifier()

float Unit::ApplyTotalThreatModifier ( float  fThreat,
SpellSchoolMask  schoolMask = SPELL_SCHOOL_MASK_NORMAL 
)
14512{
14513 if (!HasAuraType(SPELL_AURA_MOD_THREAT) || fThreat < 0)
14514 return fThreat;
14515
14516 SpellSchools school = GetFirstSchoolInMask(schoolMask);
14517
14518 return fThreat * m_threatModifier[school];
14519}
SpellSchools
Definition: SharedDefines.h:254
SpellSchools GetFirstSchoolInMask(SpellSchoolMask mask)
Definition: SharedDefines.h:290
@ SPELL_AURA_MOD_THREAT
Definition: SpellAuraDefines.h:73
bool HasAuraType(AuraType auraType) const
Definition: Unit.cpp:5605

◆ Attack()

bool Unit::Attack ( Unit victim,
bool  meleeAttack 
)
10234{
10235 if (!victim || victim == this)
10236 return false;
10237
10238 // dead units can neither attack nor be attacked
10239 if (!IsAlive() || !victim->IsAlive())
10240 return false;
10241
10242 // pussywizard: check map, world, phase >_> multithreading crash fix
10243 if (!IsInMap(victim) || !InSamePhase(victim))
10244 return false;
10245
10246 // player cannot attack in mount state
10247 if (GetTypeId() == TYPEID_PLAYER && IsMounted())
10248 return false;
10249
10250 // creatures cannot attack while evading
10251 Creature* creature = ToCreature();
10252 if (creature && creature->IsInEvadeMode())
10253 {
10254 return false;
10255 }
10256
10257 // creatures should not try to attack the player during polymorph
10258 if (creature && creature->IsPolymorphed())
10259 {
10260 return false;
10261 }
10262
10263 //if (HasUnitFlag(UNIT_FLAG_PACIFIED)) // pussywizard: why having this flag prevents from entering combat? it should just prevent melee attack
10264 // return false;
10265
10266 // nobody can attack GM in GM-mode
10267 if (victim->GetTypeId() == TYPEID_PLAYER)
10268 {
10269 if (victim->ToPlayer()->IsGameMaster())
10270 return false;
10271 }
10272 else
10273 {
10274 if (victim->ToCreature()->IsEvadingAttacks())
10275 return false;
10276 }
10277
10278 // Unit with SPELL_AURA_SPIRIT_OF_REDEMPTION can not attack
10280 return false;
10281
10282 // remove SPELL_AURA_MOD_UNATTACKABLE at attack (in case non-interruptible spells stun aura applied also that not let attack)
10285
10286 if (m_attacking)
10287 {
10288 if (m_attacking == victim)
10289 {
10290 // switch to melee attack from ranged/magic
10291 if (meleeAttack)
10292 {
10294 {
10296 SendMeleeAttackStart(victim);
10297 return true;
10298 }
10299 }
10301 {
10303 SendMeleeAttackStop(victim);
10304 return true;
10305 }
10306 return false;
10307 }
10308
10309 // switch target
10310 InterruptSpell(CURRENT_MELEE_SPELL, true, true, true);
10311 if (!meleeAttack)
10313 }
10314
10315 if (m_attacking)
10317
10318 m_attacking = victim;
10320
10321 // Set our target
10322 SetTarget(victim->GetGUID());
10323
10324 if (meleeAttack)
10326
10327 // set position before any AI calls/assistance
10328 //if (GetTypeId() == TYPEID_UNIT)
10329 // ToCreature()->SetCombatStartPosition(GetPositionX(), GetPositionY(), GetPositionZ());
10330 if (creature && !(IsControllableGuardian() && IsControlledByPlayer()))
10331 {
10332 // should not let player enter combat by right clicking target - doesn't helps
10333 SetInCombatWith(victim);
10334 if (victim->GetTypeId() == TYPEID_PLAYER)
10335 victim->SetInCombatWith(this);
10336 AddThreat(victim, 0.0f);
10337
10339
10340 creature->CallAssistance();
10342
10344 }
10345
10346 // delay offhand weapon attack to next attack time
10349
10350 if (meleeAttack)
10351 SendMeleeAttackStart(victim);
10352
10353 return true;
10354}
@ CONFIG_CREATURE_FAMILY_ASSISTANCE_PERIOD
Definition: IWorld.h:277
@ EMOTE_ONESHOT_NONE
Definition: SharedDefines.h:1866
@ AI_REACTION_HOSTILE
Definition: SharedDefines.h:3214
@ SPELL_AURA_SPIRIT_OF_REDEMPTION
Definition: SpellAuraDefines.h:239
@ SPELL_AURA_MOD_UNATTACKABLE
Definition: SpellAuraDefines.h:156
#define ATTACK_DISPLAY_DELAY
Definition: Unit.h:1238
@ CURRENT_MELEE_SPELL
Definition: Unit.h:978
@ UNIT_STATE_MELEE_ATTACKING
Definition: Unit.h:326
@ UNIT_NPC_EMOTESTATE
Definition: UpdateFields.h:140
void CallAssistance(Unit *target=nullptr)
Definition: Creature.cpp:2339
bool IsEvadingAttacks() const
Definition: Creature.h:129
void SetAssistanceTimer(uint32 value)
Definition: Creature.h:383
void SendAIReaction(AiReaction reactionType)
Definition: Creature.cpp:2327
bool IsInEvadeMode() const
Definition: Creature.h:128
void SetUInt32Value(uint16 index, uint32 value)
Definition: Object.cpp:650
bool IsGameMaster() const
Definition: Player.h:1136
void ClearUnitState(uint32 f)
Definition: Unit.h:1399
bool IsPolymorphed() const
Definition: Unit.cpp:16827
void AddThreat(Unit *victim, float fThreat, SpellSchoolMask schoolMask=SPELL_SCHOOL_MASK_NORMAL, SpellInfo const *threatSpell=nullptr)
Definition: Unit.cpp:14523
void _removeAttacker(Unit *pAttacker)
Definition: Unit.h:1362
bool haveOffhandWeapon() const
Definition: Unit.cpp:539
void _addAttacker(Unit *pAttacker)
Definition: Unit.h:1358
void SetInCombatWith(Unit *enemy, uint32 duration=0)
Definition: Unit.cpp:13485
bool IsMounted() const
Definition: Unit.h:1540
void SendMeleeAttackStart(Unit *victim, Player *sendTo=nullptr)
Definition: Unit.cpp:3011
bool IsControllableGuardian() const
Definition: Unit.h:1412
void SendMeleeAttackStop(Unit *victim=nullptr)
Definition: Unit.cpp:3023
bool IsControlledByPlayer() const
Definition: Unit.h:1825
virtual void SetTarget(ObjectGuid=ObjectGuid::Empty)=0
bool InSamePhase(WorldObject const *obj) const
Definition: Object.h:435
bool IsInMap(WorldObject const *obj) const
Definition: Object.cpp:1285
#define sWorld
Definition: World.h:458

◆ AttackerStateUpdate()

void Unit::AttackerStateUpdate ( Unit victim,
WeaponAttackType  attType = BASE_ATTACK,
bool  extra = false,
bool  ignoreCasting = false 
)
2516{
2518 {
2519 return;
2520 }
2521
2522 if (HasUnitState(UNIT_STATE_CANNOT_AUTOATTACK) && !extra && !ignoreCasting)
2523 {
2524 return;
2525 }
2526
2527 if (!victim->IsAlive())
2528 return;
2529
2530 if ((attType == BASE_ATTACK || attType == OFF_ATTACK) && !IsWithinLOSInMap(victim))
2531 return;
2532
2533 // CombatStart puts the target into stand state, so we need to cache sit state here to know if we should crit later
2534 const bool sittingVictim = victim->GetTypeId() == TYPEID_PLAYER && (victim->IsSitState() || victim->getStandState() == UNIT_STAND_STATE_SLEEP);
2535
2536 CombatStart(victim);
2538
2539 if (attType != BASE_ATTACK && attType != OFF_ATTACK)
2540 return; // ignore ranged case
2541
2542 if (!extra && _lastExtraAttackSpell)
2543 {
2545 }
2546
2547 bool meleeAttack = true;
2548
2549 // melee attack spell casted at main hand attack only - no normal melee dmg dealt
2550 if (attType == BASE_ATTACK && m_currentSpells[CURRENT_MELEE_SPELL] && !extra)
2551 {
2552 meleeAttack = false; // The melee attack is replaced by the melee spell
2553
2555 SpellCastResult castResult = meleeSpell->CheckCast(false);
2556 if (castResult != SPELL_CAST_OK)
2557 {
2558 meleeSpell->SendCastResult(castResult);
2559 meleeSpell->SendInterrupted(0);
2560
2561 meleeSpell->finish(false);
2562 meleeSpell->SetExecutedCurrently(false);
2563
2564 if (castResult == SPELL_FAILED_NO_POWER)
2565 {
2566 // Not enough rage, do a regular melee attack instead
2567 meleeAttack = true;
2568 }
2569 }
2570 else
2571 {
2572 meleeSpell->cast(true);
2573 }
2574 }
2575 if (meleeAttack)
2576 {
2577 // attack can be redirected to another target
2578 victim = GetMeleeHitRedirectTarget(victim);
2579 CalcDamageInfo damageInfo;
2580 CalculateMeleeDamage(victim, &damageInfo, attType, sittingVictim);
2581
2582 // Send log damage message to client
2583 for (uint8 i = 0; i < MAX_ITEM_PROTO_DAMAGES; ++i)
2584 {
2585 Unit::DealDamageMods(victim, damageInfo.damages[i].damage, &damageInfo.damages[i].absorb);
2586 }
2587
2588 SendAttackStateUpdate(&damageInfo);
2589
2590 //TriggerAurasProcOnEvent(damageInfo);
2591
2592 _lastDamagedTargetGuid = victim->GetGUID();
2593
2594 DealMeleeDamage(&damageInfo, true);
2595
2596 DamageInfo dmgInfo(damageInfo);
2597 Unit::ProcDamageAndSpell(damageInfo.attacker, damageInfo.target, damageInfo.procAttacker, damageInfo.procVictim, damageInfo.procEx, dmgInfo.GetDamage(),
2598 damageInfo.attackType, nullptr, nullptr, -1, nullptr, &dmgInfo);
2599
2600 if (GetTypeId() == TYPEID_PLAYER)
2601 LOG_DEBUG("entities.unit", "AttackerStateUpdate: (Player) {} attacked {} for {} dmg, absorbed {}, blocked {}, resisted {}.",
2602 GetGUID().ToString(), victim->GetGUID().ToString(), dmgInfo.GetDamage(), dmgInfo.GetAbsorb(), dmgInfo.GetBlock(), dmgInfo.GetResist());
2603 else
2604 LOG_DEBUG("entities.unit", "AttackerStateUpdate: (NPC) {} attacked {} for {} dmg, absorbed {}, blocked {}, resisted {}.",
2605 GetGUID().ToString(), victim->GetGUID().ToString(), dmgInfo.GetDamage(), dmgInfo.GetAbsorb(), dmgInfo.GetBlock(), dmgInfo.GetResist());
2606
2607 // Let the pet know we've started attacking someting. Handles melee attacks only
2608 // Spells such as auto-shot and others handled in WorldSession::HandleCastSpellOpcode
2609 if (GetTypeId() == TYPEID_PLAYER && !m_Controlled.empty())
2610 for (Unit::ControlSet::iterator itr = m_Controlled.begin(); itr != m_Controlled.end(); ++itr)
2611 if (Unit* pet = *itr)
2612 if (pet->IsAlive() && pet->GetTypeId() == TYPEID_UNIT)
2613 pet->ToCreature()->AI()->OwnerAttacked(victim);
2614 }
2615}
#define MAX_ITEM_PROTO_DAMAGES
Definition: ItemTemplate.h:622
@ SPELL_FAILED_NO_POWER
Definition: SharedDefines.h:1006
@ AURA_INTERRUPT_FLAG_MELEE_ATTACK
Definition: SpellDefines.h:56
@ UNIT_STAND_STATE_SLEEP
Definition: Unit.h:56
@ UNIT_STATE_CANNOT_AUTOATTACK
Definition: Unit.h:368
@ UNIT_FLAG_PACIFIED
Definition: Unit.h:465
Definition: Unit.h:761
std::string ToString() const
Definition: ObjectGuid.cpp:47
void cast(bool skipCheck=false)
Definition: Spell.cpp:3753
void SetExecutedCurrently(bool yes)
Definition: Spell.h:560
void SendInterrupted(uint8 result)
Definition: Spell.cpp:5124
static void SendCastResult(Player *caster, SpellInfo const *spellInfo, uint8 castCount, SpellCastResult result, SpellCustomErrors customError=SPELL_CUSTOM_ERROR_NONE)
Definition: Spell.cpp:4619
void finish(bool ok=true)
Definition: Spell.cpp:4437
void SendAttackStateUpdate(CalcDamageInfo *damageInfo)
Definition: Unit.cpp:6379
void CombatStart(Unit *target, bool initialAggro=true)
Definition: Unit.cpp:13529
Unit * GetMeleeHitRedirectTarget(Unit *victim, SpellInfo const *spellInfo=nullptr)
Definition: Unit.cpp:11005
void CalculateMeleeDamage(Unit *victim, CalcDamageInfo *damageInfo, WeaponAttackType attackType=BASE_ATTACK, const bool sittingVictim=false)
Definition: Unit.cpp:1460
static void ProcDamageAndSpell(Unit *actor, Unit *victim, uint32 procAttacker, uint32 procVictim, uint32 procEx, uint32 amount, WeaponAttackType attType=BASE_ATTACK, SpellInfo const *procSpellInfo=nullptr, SpellInfo const *procAura=nullptr, int8 procAuraEffectIndex=-1, Spell const *procSpell=nullptr, DamageInfo *damageInfo=nullptr, HealInfo *healInfo=nullptr, uint32 procPhase=2)
Definition: Unit.cpp:6278
uint8 getStandState() const
Definition: Unit.h:1532
void DealMeleeDamage(CalcDamageInfo *damageInfo, bool durabilityLoss)
Definition: Unit.cpp:1809
static void DealDamageMods(Unit const *victim, uint32 &damage, uint32 *absorb)
Definition: Unit.cpp:804
bool IsWithinLOSInMap(WorldObject const *obj, VMAP::ModelIgnoreFlags ignoreFlags=VMAP::ModelIgnoreFlags::Nothing, LineOfSightChecks checks=LINEOFSIGHT_ALL_CHECKS, Optional< float > collisionHeight={ }) const
Definition: Object.cpp:1347
Definition: Unit.h:882
uint32 procAttacker
Definition: Unit.h:899
uint32 procVictim
Definition: Unit.h:900
uint32 absorb
Definition: Unit.h:890
uint32 damage
Definition: Unit.h:889
uint32 procEx
Definition: Unit.h:901
Unit * attacker
Definition: Unit.h:883
struct CalcDamageInfo::@247 damages[MAX_ITEM_PROTO_DAMAGES]
Unit * target
Definition: Unit.h:884
WeaponAttackType attackType
Definition: Unit.h:898
std::string ToString() const
Definition: Position.cpp:51

◆ AttackStop()

bool Unit::AttackStop ( )
10357{
10358 if (!m_attacking)
10359 return false;
10360
10361 Unit* victim = m_attacking;
10362
10364 m_attacking = nullptr;
10365
10366 // Clear our target
10368
10370
10372
10373 // reset only at real combat stop
10374 if (Creature* creature = ToCreature())
10375 {
10376 creature->SetNoCallAssistance(false);
10377
10378 if (creature->HasSearchedAssistance())
10379 {
10380 creature->SetNoSearchAssistance(false);
10381 }
10382 }
10383
10384 SendMeleeAttackStop(victim);
10385
10386 return true;
10387}

◆ BuildAuraStateUpdateForTarget()

uint32 Unit::BuildAuraStateUpdateForTarget ( Unit target) const
10485{
10487 for (AuraStateAurasMap::const_iterator itr = m_auraStateAuras.begin(); itr != m_auraStateAuras.end(); ++itr)
10488 if ((1 << (itr->first - 1)) & PER_CASTER_AURA_STATE_MASK)
10489 if (itr->second->GetBase()->GetCasterGUID() == target->GetGUID())
10490 auraStates |= (1 << (itr->first - 1));
10491
10492 return auraStates;
10493}
#define PER_CASTER_AURA_STATE_MASK
Definition: SharedDefines.h:1290
@ UNIT_FIELD_AURASTATE
Definition: UpdateFields.h:119
uint32 GetUInt32Value(uint16 index) const
Definition: Object.cpp:305

◆ BuildCooldownPacket() [1/2]

void Unit::BuildCooldownPacket ( WorldPacket data,
uint8  flags,
PacketCooldowns const &  cooldowns 
)
21011{
21012 data.Initialize(SMSG_SPELL_COOLDOWN, 8 + 1 + (4 + 4) * cooldowns.size());
21013 data << GetGUID();
21014 data << uint8(flags);
21015 for (std::unordered_map<uint32, uint32>::const_iterator itr = cooldowns.begin(); itr != cooldowns.end(); ++itr)
21016 {
21017 data << uint32(itr->first);
21018 data << uint32(itr->second);
21019 }
21020}
void Initialize(uint16 opcode, size_t newres=200)
Definition: WorldPacket.h:69
@ SMSG_SPELL_COOLDOWN
Definition: Opcodes.h:338

◆ BuildCooldownPacket() [2/2]

void Unit::BuildCooldownPacket ( WorldPacket data,
uint8  flags,
uint32  spellId,
uint32  cooldown 
)
21002{
21003 data.Initialize(SMSG_SPELL_COOLDOWN, 8 + 1 + 4 + 4);
21004 data << GetGUID();
21005 data << uint8(flags);
21006 data << uint32(spellId);
21007 data << uint32(cooldown);
21008}

◆ BuildHeartBeatMsg()

void Unit::BuildHeartBeatMsg ( WorldPacket data) const
2035{
2036 data->Initialize(MSG_MOVE_HEARTBEAT, 32);
2037 *data << GetPackGUID();
2038 BuildMovementPacket(data);
2039}
void BuildMovementPacket(ByteBuffer *data) const
Definition: Unit.cpp:19910
@ MSG_MOVE_HEARTBEAT
Definition: Opcodes.h:268

◆ BuildMovementPacket()

void Unit::BuildMovementPacket ( ByteBuffer data) const
19911{
19912 *data << uint32(GetUnitMovementFlags()); // movement flags
19913 *data << uint16(GetExtraUnitMovementFlags()); // 2.3.0
19914 *data << uint32(GameTime::GetGameTimeMS().count()); // time / counter
19915 *data << GetPositionX();
19916 *data << GetPositionY();
19917 *data << GetPositionZ();
19918 *data << GetOrientation();
19919
19920 // 0x00000200
19922 {
19923 if (m_vehicle)
19924 *data << m_vehicle->GetBase()->GetPackGUID();
19925 else if (GetTransport())
19926 *data << GetTransport()->GetPackGUID();
19927 else
19928 *data << (uint8)0;
19929
19930 *data << float (GetTransOffsetX());
19931 *data << float (GetTransOffsetY());
19932 *data << float (GetTransOffsetZ());
19933 *data << float (GetTransOffsetO());
19934 *data << uint32(GetTransTime());
19935 *data << uint8 (GetTransSeat());
19936
19939 }
19940
19941 // 0x02200000
19944 *data << (float)m_movementInfo.pitch;
19945
19946 *data << (uint32)m_movementInfo.fallTime;
19947
19948 // 0x00001000
19950 {
19951 *data << (float)m_movementInfo.jump.zspeed;
19952 *data << (float)m_movementInfo.jump.sinAngle;
19953 *data << (float)m_movementInfo.jump.cosAngle;
19954 *data << (float)m_movementInfo.jump.xyspeed;
19955 }
19956
19957 // 0x04000000
19959 *data << (float)m_movementInfo.splineElevation;
19960}
@ MOVEMENTFLAG_ONTRANSPORT
Definition: Unit.h:561
@ MOVEMENTFLAG_FLYING
Definition: Unit.h:577
@ MOVEMENTFLAG_FALLING
Definition: Unit.h:564
@ MOVEMENTFLAG_SWIMMING
Definition: Unit.h:573
@ MOVEMENTFLAG_SPLINE_ELEVATION
Definition: Unit.h:578
@ MOVEMENTFLAG2_ALWAYS_ALLOW_PITCHING
Definition: Unit.h:613
@ MOVEMENTFLAG2_INTERPOLATED_MOVEMENT
Definition: Unit.h:618
uint32 GetUnitMovementFlags() const
Definition: Unit.h:2270
uint16 GetExtraUnitMovementFlags() const
Definition: Unit.h:2276
float GetTransOffsetX() const
Definition: Object.h:586
float GetTransOffsetY() const
Definition: Object.h:587
float GetTransOffsetZ() const
Definition: Object.h:588
uint32 GetTransTime() const
Definition: Object.h:590
Transport * GetTransport() const
Definition: Object.h:585
float GetTransOffsetO() const
Definition: Object.h:589
float cosAngle
Definition: Object.h:305
float xyspeed
Definition: Object.h:305
float zspeed
Definition: Object.h:305
float sinAngle
Definition: Object.h:305
uint32 time2
Definition: Object.h:288
struct MovementInfo::JumpInfo jump
uint32 fallTime
Definition: Object.h:295
struct MovementInfo::TransportInfo transport
float splineElevation
Definition: Object.h:309
float pitch
Definition: Object.h:292

◆ BuildValuesUpdate()

void Unit::BuildValuesUpdate ( uint8  updatetype,
ByteBuffer data,
Player target 
) const
overrideprotectedvirtual

Reimplemented from Object.

20793{
20794 if (!target)
20795 return;
20796
20797 ByteBuffer fieldBuffer;
20798
20799 UpdateMask updateMask;
20800 updateMask.SetCount(m_valuesCount);
20801
20803 uint32 visibleFlag = UF_FLAG_PUBLIC;
20804
20805 if (target == this)
20806 visibleFlag |= UF_FLAG_PRIVATE;
20807
20809 if (GetOwnerGUID() == target->GetGUID())
20810 visibleFlag |= UF_FLAG_OWNER;
20811
20814 visibleFlag |= UF_FLAG_SPECIAL_INFO;
20815
20816 if (plr && plr->IsInSameRaidWith(target))
20817 visibleFlag |= UF_FLAG_PARTY_MEMBER;
20818
20819 Creature const* creature = ToCreature();
20820 for (uint16 index = 0; index < m_valuesCount; ++index)
20821 {
20822 if (_fieldNotifyFlags & flags[index] ||
20823 ((flags[index] & visibleFlag) & UF_FLAG_SPECIAL_INFO) ||
20824 ((updateType == UPDATETYPE_VALUES ? _changesMask.GetBit(index) : m_uint32Values[index]) && (flags[index] & visibleFlag)) ||
20826 {
20827 updateMask.SetBit(index);
20828
20829 if (index == UNIT_NPC_FLAGS)
20830 {
20831 uint32 appendValue = m_uint32Values[UNIT_NPC_FLAGS];
20832
20833 if (creature)
20834 {
20835 if (sWorld->getIntConfig(CONFIG_INSTANT_TAXI) == 2 && appendValue & UNIT_NPC_FLAG_FLIGHTMASTER)
20836 {
20837 appendValue |= UNIT_NPC_FLAG_GOSSIP; // flight masters need NPC gossip flag to show instant flight toggle option
20838 }
20839
20840 if (!target->CanSeeSpellClickOn(creature))
20841 {
20842 appendValue &= ~UNIT_NPC_FLAG_SPELLCLICK;
20843 }
20844
20845 if (!target->CanSeeVendor(creature))
20846 {
20847 appendValue &= ~UNIT_NPC_FLAG_VENDOR_MASK;
20848 }
20849
20850 if (!creature->IsValidTrainerForPlayer(target, &appendValue))
20851 {
20852 appendValue &= ~UNIT_NPC_FLAG_TRAINER;
20853 }
20854 }
20855
20856 fieldBuffer << uint32(appendValue);
20857 }
20858 else if (index == UNIT_FIELD_AURASTATE)
20859 {
20860 // Check per caster aura states to not enable using a spell in client if specified aura is not by target
20861 fieldBuffer << BuildAuraStateUpdateForTarget(target);
20862 }
20863 // FIXME: Some values at server stored in float format but must be sent to client in uint32 format
20864 else if (index >= UNIT_FIELD_BASEATTACKTIME && index <= UNIT_FIELD_RANGEDATTACKTIME)
20865 {
20866 // convert from float to uint32 and send
20867 fieldBuffer << uint32(m_floatValues[index] < 0 ? 0 : m_floatValues[index]);
20868 }
20869 // there are some float values which may be negative or can't get negative due to other checks
20870 else if ((index >= UNIT_FIELD_NEGSTAT0 && index <= UNIT_FIELD_NEGSTAT4) ||
20873 (index >= UNIT_FIELD_POSSTAT0 && index <= UNIT_FIELD_POSSTAT4))
20874 {
20875 fieldBuffer << uint32(m_floatValues[index]);
20876 }
20877 // Gamemasters should be always able to select units - remove not selectable flag
20878 else if (index == UNIT_FIELD_FLAGS)
20879 {
20880 uint32 appendValue = m_uint32Values[UNIT_FIELD_FLAGS];
20881 if (target->IsGameMaster() && AccountMgr::IsGMAccount(target->GetSession()->GetSecurity()))
20882 appendValue &= ~UNIT_FLAG_NOT_SELECTABLE;
20883
20884 fieldBuffer << uint32(appendValue);
20885 }
20886 // use modelid_a if not gm, _h if gm for CREATURE_FLAG_EXTRA_TRIGGER creatures
20887 else if (index == UNIT_FIELD_DISPLAYID)
20888 {
20890 if (creature)
20891 {
20892 CreatureTemplate const* cinfo = creature->GetCreatureTemplate();
20893
20894 // this also applies for transform auras
20895 if (SpellInfo const* transform = sSpellMgr->GetSpellInfo(getTransForm()))
20896 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
20897 if (transform->Effects[i].IsAura(SPELL_AURA_TRANSFORM))
20898 if (CreatureTemplate const* transformInfo = sObjectMgr->GetCreatureTemplate(transform->Effects[i].MiscValue))
20899 {
20900 cinfo = transformInfo;
20901 break;
20902 }
20903
20905 {
20906 if (target->IsGameMaster() && AccountMgr::IsGMAccount(target->GetSession()->GetSecurity()))
20907 {
20908 if (cinfo->Modelid1)
20909 displayId = cinfo->Modelid1; // Modelid1 is a visible model for gms
20910 else
20911 displayId = 17519; // world visible trigger's model
20912 }
20913 else
20914 {
20915 if (cinfo->Modelid2)
20916 displayId = cinfo->Modelid2; // Modelid2 is an invisible model for players
20917 else
20918 displayId = 11686; // world invisible trigger's model
20919 }
20920 }
20921 }
20922
20923 fieldBuffer << uint32(displayId);
20924 }
20925 // hide lootable animation for unallowed players
20926 else if (index == UNIT_DYNAMIC_FLAGS)
20927 {
20929
20930 if (creature)
20931 {
20932 if (creature->hasLootRecipient())
20933 {
20934 dynamicFlags |= UNIT_DYNFLAG_TAPPED;
20935 if (creature->isTappedBy(target))
20936 dynamicFlags |= UNIT_DYNFLAG_TAPPED_BY_PLAYER;
20937 }
20938
20939 if (!target->isAllowedToLoot(creature))
20940 dynamicFlags &= ~UNIT_DYNFLAG_LOOTABLE;
20941 }
20942
20943 // unit UNIT_DYNFLAG_TRACK_UNIT should only be sent to caster of SPELL_AURA_MOD_STALKED auras
20944 if (dynamicFlags & UNIT_DYNFLAG_TRACK_UNIT)
20946 dynamicFlags &= ~UNIT_DYNFLAG_TRACK_UNIT;
20947
20948 fieldBuffer << dynamicFlags;
20949 }
20950 // FG: pretend that OTHER players in own group are friendly ("blue")
20951 else if (index == UNIT_FIELD_BYTES_2 || index == UNIT_FIELD_FACTIONTEMPLATE)
20952 {
20953 if (IsControlledByPlayer() && target != this && sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_GROUP) && IsInRaidWith(target))
20954 {
20956 FactionTemplateEntry const* ft2 = target->GetFactionTemplateEntry();
20957 if (ft1 && ft2 && !ft1->IsFriendlyTo(*ft2))
20958 {
20959 if (index == UNIT_FIELD_BYTES_2)
20960 // Allow targetting opposite faction in party when enabled in config
20961 fieldBuffer << (m_uint32Values[UNIT_FIELD_BYTES_2] & ((UNIT_BYTE2_FLAG_SANCTUARY /*| UNIT_BYTE2_FLAG_AURAS | UNIT_BYTE2_FLAG_UNK5*/) << 8)); // this flag is at uint8 offset 1 !!
20962 else
20963 // pretend that all other HOSTILE players have own faction, to allow follow, heal, rezz (trade wont work)
20964 fieldBuffer << uint32(target->GetFaction());
20965 }
20966 else
20967 fieldBuffer << m_uint32Values[index];
20968 }// pussywizard / Callmephil
20969 else if (target->IsSpectator() && target->FindMap() && target->FindMap()->IsBattleArena() &&
20970 (this->GetTypeId() == TYPEID_PLAYER || this->GetTypeId() == TYPEID_UNIT || this->GetTypeId() == TYPEID_DYNAMICOBJECT))
20971 {
20972 if (index == UNIT_FIELD_BYTES_2)
20973 fieldBuffer << (m_uint32Values[index] & 0xFFFFF2FF); // clear UNIT_BYTE2_FLAG_PVP, UNIT_BYTE2_FLAG_FFA_PVP, UNIT_BYTE2_FLAG_SANCTUARY
20974 else
20975 fieldBuffer << (uint32)target->GetFaction();
20976 }
20977 else
20978 if (!sScriptMgr->IsCustomBuildValuesUpdate(this, updateType, fieldBuffer, target, index))
20979 {
20980 fieldBuffer << m_uint32Values[index];
20981 }
20982 }
20983 else
20984 {
20985 if (sScriptMgr->OnBuildValuesUpdate(this, updateType, fieldBuffer, target, index))
20986 {
20987 continue;
20988 }
20989
20990 // send in current format (float as float, uint32 as uint32)
20991 fieldBuffer << m_uint32Values[index];
20992 }
20993 }
20994 }
20995
20996 *data << uint8(updateMask.GetBlockCount());
20997 updateMask.AppendToPacket(data);
20998 data->append(fieldBuffer);
20999}
@ CREATURE_FLAG_EXTRA_TRIGGER
Definition: CreatureData.h:56
@ CONFIG_INSTANT_TAXI
Definition: IWorld.h:373
@ CONFIG_ALLOW_TWO_SIDE_INTERACTION_GROUP
Definition: IWorld.h:80
@ TYPEID_DYNAMICOBJECT
Definition: ObjectGuid.h:40
#define sObjectMgr
Definition: ObjectMgr.h:1606
@ UNIT_DYNFLAG_SPECIALINFO
Definition: SharedDefines.h:3097
@ UNIT_DYNFLAG_TAPPED_BY_PLAYER
Definition: SharedDefines.h:3096
@ UNIT_DYNFLAG_TAPPED
Definition: SharedDefines.h:3095
@ UNIT_DYNFLAG_LOOTABLE
Definition: SharedDefines.h:3093
@ UNIT_DYNFLAG_TRACK_UNIT
Definition: SharedDefines.h:3094
@ SPELL_AURA_EMPATHY
Definition: SpellAuraDefines.h:184
@ SPELL_AURA_MOD_STALKED
Definition: SpellAuraDefines.h:131
@ SPELL_AURA_TRANSFORM
Definition: SpellAuraDefines.h:119
@ UNIT_NPC_FLAG_GOSSIP
Definition: Unit.h:516
@ UNIT_NPC_FLAG_FLIGHTMASTER
Definition: Unit.h:529
@ UNIT_BYTE2_FLAG_SANCTUARY
Definition: Unit.h:139
@ UPDATETYPE_VALUES
Definition: UpdateData.h:28
uint32 UnitUpdateFieldFlags[PLAYER_END]
Definition: UpdateFieldFlags.cpp:162
@ UF_FLAG_SPECIAL_INFO
Definition: UpdateFieldFlags.h:32
@ UF_FLAG_PUBLIC
Definition: UpdateFieldFlags.h:27
@ UF_FLAG_OWNER
Definition: UpdateFieldFlags.h:29
@ UF_FLAG_PRIVATE
Definition: UpdateFieldFlags.h:28
@ UF_FLAG_PARTY_MEMBER
Definition: UpdateFieldFlags.h:33
@ UNIT_NPC_FLAGS
Definition: UpdateFields.h:139
@ UNIT_FIELD_RANGEDATTACKTIME
Definition: UpdateFields.h:121
@ UNIT_FIELD_DISPLAYID
Definition: UpdateFields.h:124
@ UNIT_FIELD_FACTIONTEMPLATE
Definition: UpdateFields.h:115
@ UNIT_FIELD_POSSTAT4
Definition: UpdateFields.h:150
@ UNIT_FIELD_NEGSTAT4
Definition: UpdateFields.h:155
@ UNIT_FIELD_FLAGS
Definition: UpdateFields.h:117
@ UNIT_DYNAMIC_FLAGS
Definition: UpdateFields.h:136
Definition: ByteBuffer.h:70
void append(T value)
Definition: ByteBuffer.h:129
bool IsValidTrainerForPlayer(Player *player, uint32 *npcFlags=nullptr) const
Definition: Creature.cpp:1221
bool hasLootRecipient() const
Definition: Creature.h:222
bool isTappedBy(Player const *player) const
Definition: Creature.cpp:1337
bool IsBattleArena() const
Definition: Map.h:454
uint16 _fieldNotifyFlags
Definition: Object.h:244
bool HasDynamicFlag(uint32 flag) const
Definition: Object.h:116
UpdateMask _changesMask
Definition: Object.h:240
uint32 * m_uint32Values
Definition: Object.h:236
uint16 m_valuesCount
Definition: Object.h:242
bool HasFlag(uint16 index, uint32 flag) const
Definition: Object.cpp:889
float * m_floatValues
Definition: Object.h:237
bool isAllowedToLoot(Creature const *creature)
Definition: PlayerStorage.cpp:5644
bool IsInSameRaidWith(Player const *p) const
Definition: Player.h:1835
WorldSession * GetSession() const
Definition: Player.h:1947
bool CanSeeVendor(Creature const *creature) const
Definition: Player.cpp:13993
bool IsSpectator() const
Definition: Player.h:2521
bool CanSeeSpellClickOn(Creature const *creature) const
Definition: Player.cpp:13970
Player * GetCharmerOrOwnerPlayerOrPlayerItself() const
Definition: Unit.cpp:10564
bool HasAuraTypeWithCaster(AuraType auratype, ObjectGuid caster) const
Definition: Unit.cpp:5610
uint32 GetFaction() const
Definition: Unit.h:1493
uint32 BuildAuraStateUpdateForTarget(Unit *target) const
Definition: Unit.cpp:10484
bool IsInRaidWith(Unit const *unit) const
Definition: Unit.cpp:18829
ObjectGuid GetOwnerGUID() const
Definition: Unit.h:1811
uint32 getTransForm() const
Definition: Unit.h:2169
Definition: UpdateMask.h:26
uint32 GetBlockCount() const
Definition: UpdateMask.h:63
bool GetBit(uint32 index) const
Definition: UpdateMask.h:48
void SetCount(uint32 valuesCount)
Definition: UpdateMask.h:66
void SetBit(uint32 index)
Definition: UpdateMask.h:46
void AppendToPacket(ByteBuffer *data)
Definition: UpdateMask.h:50
Map * FindMap() const
Definition: Object.h:518
AccountTypes GetSecurity() const
Definition: WorldSession.h:357
bool IsGMAccount(uint32 gmlevel)
Definition: AccountMgr.cpp:281
Definition: CreatureData.h:176
uint32 Modelid1
Definition: CreatureData.h:180
uint32 Modelid2
Definition: CreatureData.h:181
bool IsFriendlyTo(FactionTemplateEntry const &entry) const
Definition: DBCStructure.h:942

◆ CalcAbsorbResist()

void Unit::CalcAbsorbResist ( DamageInfo dmgInfo,
bool  Splited = false 
)
static
2106{
2107 Unit* victim = dmgInfo.GetVictim();
2108 Unit* attacker = dmgInfo.GetAttacker();
2109 uint32 damage = dmgInfo.GetDamage();
2110 SpellSchoolMask schoolMask = dmgInfo.GetSchoolMask();
2111 SpellInfo const* spellInfo = dmgInfo.GetSpellInfo();
2112
2113 if (!victim || !victim->IsAlive() || !damage)
2114 return;
2115
2116 // Magic damage, check for resists
2117 // Ignore spells that cant be resisted
2118 // Xinef: holy resistance exists for npcs
2119 if (!(schoolMask & SPELL_SCHOOL_MASK_NORMAL) && (!(schoolMask & SPELL_SCHOOL_MASK_HOLY) || victim->GetTypeId() == TYPEID_UNIT) && (!spellInfo || (!spellInfo->HasAttribute(SPELL_ATTR0_CU_BINARY_SPELL) && !spellInfo->HasAttribute(SPELL_ATTR4_NO_CAST_LOG))))
2120 {
2121 float averageResist = Unit::GetEffectiveResistChance(attacker, schoolMask, victim);
2122
2123 float discreteResistProbability[11];
2124 for (uint32 i = 0; i < 11; ++i)
2125 {
2126 discreteResistProbability[i] = 0.5f - 2.5f * std::fabs(0.1f * i - averageResist);
2127 if (discreteResistProbability[i] < 0.0f)
2128 discreteResistProbability[i] = 0.0f;
2129 }
2130
2131 if (averageResist <= 0.1f)
2132 {
2133 discreteResistProbability[0] = 1.0f - 7.5f * averageResist;
2134 discreteResistProbability[1] = 5.0f * averageResist;
2135 discreteResistProbability[2] = 2.5f * averageResist;
2136 }
2137
2138 float r = float(rand_norm());
2139 uint32 i = 0;
2140 float probabilitySum = discreteResistProbability[0];
2141
2142 while (r >= probabilitySum && i < 10)
2143 probabilitySum += discreteResistProbability[++i];
2144
2145 float damageResisted = float(damage * i / 10);
2146
2147 if (damageResisted) // if equal to 0, checking these is pointless
2148 {
2149 if (attacker)
2150 {
2152 for (AuraEffectList::const_iterator j = ResIgnoreAurasAb.begin(); j != ResIgnoreAurasAb.end(); ++j)
2153 if (((*j)->GetMiscValue() & schoolMask) && (*j)->IsAffectedOnSpell(spellInfo))
2154 AddPct(damageResisted, -(*j)->GetAmount());
2155
2157 for (AuraEffectList::const_iterator j = ResIgnoreAuras.begin(); j != ResIgnoreAuras.end(); ++j)
2158 if ((*j)->GetMiscValue() & schoolMask)
2159 AddPct(damageResisted, -(*j)->GetAmount());
2160 }
2161
2162 // pussywizard:
2163 if (spellInfo && spellInfo->HasAttribute(SPELL_ATTR0_CU_SCHOOLMASK_NORMAL_WITH_MAGIC))
2164 {
2165 uint32 damageAfterArmor = Unit::CalcArmorReducedDamage(attacker, victim, damage, spellInfo, 0, BASE_ATTACK);
2166 uint32 armorReduction = damage - damageAfterArmor;
2167 if (armorReduction < damageResisted) // pick the lower one, the weakest resistance counts
2168 damageResisted = armorReduction;
2169 }
2170 }
2171
2172 dmgInfo.ResistDamage(uint32(damageResisted));
2173 }
2174
2175 // Ignore Absorption Auras
2176 float auraAbsorbMod = 0;
2177 if (attacker)
2178 {
2180 for (AuraEffectList::const_iterator itr = AbsIgnoreAurasA.begin(); itr != AbsIgnoreAurasA.end(); ++itr)
2181 {
2182 if (!((*itr)->GetMiscValue() & schoolMask))
2183 continue;
2184
2185 if ((*itr)->GetAmount() > auraAbsorbMod)
2186 auraAbsorbMod = float((*itr)->GetAmount());
2187 }
2188
2190 for (AuraEffectList::const_iterator itr = AbsIgnoreAurasB.begin(); itr != AbsIgnoreAurasB.end(); ++itr)
2191 {
2192 if (!((*itr)->GetMiscValue() & schoolMask))
2193 continue;
2194
2195 if (((*itr)->GetAmount() > auraAbsorbMod) && (*itr)->IsAffectedOnSpell(spellInfo))
2196 auraAbsorbMod = float((*itr)->GetAmount());
2197 }
2198 RoundToInterval(auraAbsorbMod, 0.0f, 100.0f);
2199 }
2200
2201 // We're going to call functions which can modify content of the list during iteration over it's elements
2202 // Let's copy the list so we can prevent iterator invalidation
2204 vSchoolAbsorbCopy.sort(Acore::AbsorbAuraOrderPred());
2205
2206 // absorb without mana cost
2207 for (AuraEffectList::iterator itr = vSchoolAbsorbCopy.begin(); (itr != vSchoolAbsorbCopy.end()) && (dmgInfo.GetDamage() > 0); ++itr)
2208 {
2209 AuraEffect* absorbAurEff = *itr;
2210 // Check if aura was removed during iteration - we don't need to work on such auras
2211 AuraApplication const* aurApp = absorbAurEff->GetBase()->GetApplicationOfTarget(victim->GetGUID());
2212 if (!aurApp)
2213 continue;
2214 if (!(absorbAurEff->GetMiscValue() & schoolMask))
2215 continue;
2216
2217 // get amount which can be still absorbed by the aura
2218 int32 currentAbsorb = absorbAurEff->GetAmount();
2219 // aura with infinite absorb amount - let the scripts handle absorbtion amount, set here to 0 for safety
2220 if (currentAbsorb < 0)
2221 currentAbsorb = 0;
2222
2223 uint32 tempAbsorb = uint32(currentAbsorb);
2224
2225 bool defaultPrevented = false;
2226
2227 absorbAurEff->GetBase()->CallScriptEffectAbsorbHandlers(absorbAurEff, aurApp, dmgInfo, tempAbsorb, defaultPrevented);
2228 currentAbsorb = tempAbsorb;
2229
2230 if (defaultPrevented)
2231 continue;
2232
2233 // absorb must be smaller than the damage itself
2234 currentAbsorb = RoundToInterval(currentAbsorb, 0, int32(dmgInfo.GetDamage()));
2235
2236 // xinef: do this after absorb is rounded to damage...
2237 AddPct(currentAbsorb, -auraAbsorbMod);
2238
2239 dmgInfo.AbsorbDamage(currentAbsorb);
2240
2241 tempAbsorb = currentAbsorb;
2242 absorbAurEff->GetBase()->CallScriptEffectAfterAbsorbHandlers(absorbAurEff, aurApp, dmgInfo, tempAbsorb);
2243
2244 // Check if our aura is using amount to count damage
2245 if (absorbAurEff->GetAmount() >= 0)
2246 {
2247 // Reduce shield amount
2248 absorbAurEff->SetAmount(absorbAurEff->GetAmount() - currentAbsorb);
2249 // Aura cannot absorb anything more - remove it
2250 if (absorbAurEff->GetAmount() <= 0)
2251 absorbAurEff->GetBase()->Remove(AURA_REMOVE_BY_ENEMY_SPELL);
2252 }
2253 }
2254
2255 // absorb by mana cost
2257 for (AuraEffectList::const_iterator itr = vManaShieldCopy.begin(); (itr != vManaShieldCopy.end()) && (dmgInfo.GetDamage() > 0); ++itr)
2258 {
2259 AuraEffect* absorbAurEff = *itr;
2260 // Check if aura was removed during iteration - we don't need to work on such auras
2261 AuraApplication const* aurApp = absorbAurEff->GetBase()->GetApplicationOfTarget(victim->GetGUID());
2262 if (!aurApp)
2263 continue;
2264 // check damage school mask
2265 if (!(absorbAurEff->GetMiscValue() & schoolMask))
2266 continue;
2267
2268 // get amount which can be still absorbed by the aura
2269 int32 currentAbsorb = absorbAurEff->GetAmount();
2270 // aura with infinite absorb amount - let the scripts handle absorbtion amount, set here to 0 for safety
2271 if (currentAbsorb < 0)
2272 currentAbsorb = 0;
2273
2274 uint32 tempAbsorb = currentAbsorb;
2275
2276 bool defaultPrevented = false;
2277
2278 absorbAurEff->GetBase()->CallScriptEffectManaShieldHandlers(absorbAurEff, aurApp, dmgInfo, tempAbsorb, defaultPrevented);
2279 currentAbsorb = tempAbsorb;
2280
2281 if (defaultPrevented)
2282 continue;
2283
2284 // absorb must be smaller than the damage itself
2285 currentAbsorb = RoundToInterval(currentAbsorb, 0, int32(dmgInfo.GetDamage()));
2286
2287 // xinef: do this after absorb is rounded to damage...
2288 AddPct(currentAbsorb, -auraAbsorbMod);
2289
2290 int32 manaReduction = currentAbsorb;
2291
2292 // lower absorb amount by talents
2293 if (float manaMultiplier = absorbAurEff->GetSpellInfo()->Effects[absorbAurEff->GetEffIndex()].CalcValueMultiplier(absorbAurEff->GetCaster()))
2294 manaReduction = int32(float(manaReduction) * manaMultiplier);
2295
2296 int32 manaTaken = -victim->ModifyPower(POWER_MANA, -manaReduction);
2297
2298 // take case when mana has ended up into account
2299 currentAbsorb = currentAbsorb ? int32(float(currentAbsorb) * (float(manaTaken) / float(manaReduction))) : 0;
2300
2301 dmgInfo.AbsorbDamage(currentAbsorb);
2302
2303 tempAbsorb = currentAbsorb;
2304 absorbAurEff->GetBase()->CallScriptEffectAfterManaShieldHandlers(absorbAurEff, aurApp, dmgInfo, tempAbsorb);
2305
2306 // Check if our aura is using amount to count damage
2307 if (absorbAurEff->GetAmount() >= 0)
2308 {
2309 absorbAurEff->SetAmount(absorbAurEff->GetAmount() - currentAbsorb);
2310 if ((absorbAurEff->GetAmount() <= 0))
2311 absorbAurEff->GetBase()->Remove(AURA_REMOVE_BY_ENEMY_SPELL);
2312 }
2313 }
2314
2315 // split damage auras - only when not damaging self
2316 // Xinef: not true - Warlock Hellfire
2317 if (/*victim != attacker &&*/ !Splited)
2318 {
2319 // We're going to call functions which can modify content of the list during iteration over it's elements
2320 // Let's copy the list so we can prevent iterator invalidation
2322 for (AuraEffectList::iterator itr = vSplitDamageFlatCopy.begin(); (itr != vSplitDamageFlatCopy.end()) && (dmgInfo.GetDamage() > 0); ++itr)
2323 {
2324 // Check if aura was removed during iteration - we don't need to work on such auras
2325 if (!((*itr)->GetBase()->IsAppliedOnTarget(victim->GetGUID())))
2326 continue;
2327 // check damage school mask
2328 if (!((*itr)->GetMiscValue() & schoolMask))
2329 continue;
2330
2331 // Damage can be splitted only if aura has an alive caster
2332 Unit* caster = (*itr)->GetCaster();
2333 if (!caster || (caster == victim) || !caster->IsInWorld() || !caster->IsAlive())
2334 continue;
2335
2336 int32 splitDamage = (*itr)->GetAmount();
2337
2338 // absorb must be smaller than the damage itself
2339 splitDamage = RoundToInterval(splitDamage, 0, int32(dmgInfo.GetDamage()));
2340
2341 dmgInfo.AbsorbDamage(splitDamage);
2342
2343 uint32 splitted = splitDamage;
2344 uint32 splitted_absorb = 0;
2345 uint32 splitted_resist = 0;
2346
2347 uint32 procAttacker = 0, procVictim = 0, procEx = PROC_EX_NORMAL_HIT;
2348 DamageInfo splittedDmgInfo(attacker, caster, splitted, spellInfo, schoolMask, dmgInfo.GetDamageType());
2349 if (caster->IsImmunedToDamageOrSchool(schoolMask))
2350 {
2351 procEx |= PROC_EX_IMMUNE;
2352 splittedDmgInfo.AbsorbDamage(splitted);
2353 }
2354 else
2355 {
2356 Unit::CalcAbsorbResist(splittedDmgInfo, true);
2357 Unit::DealDamageMods(caster, splitted, &splitted_absorb);
2358 }
2359
2360 splitted_absorb = splittedDmgInfo.GetAbsorb();
2361 splitted_resist = splittedDmgInfo.GetResist();
2362 splitted = splittedDmgInfo.GetDamage();
2363
2364 // create procs
2365 createProcFlags(spellInfo, BASE_ATTACK, false, procAttacker, procVictim);
2366 caster->ProcDamageAndSpellFor(true, attacker, procVictim, procEx, BASE_ATTACK, spellInfo, splitted, nullptr, -1, nullptr, &splittedDmgInfo);
2367
2368 if (attacker)
2369 {
2370 attacker->SendSpellNonMeleeDamageLog(caster, (*itr)->GetSpellInfo(), splitted, schoolMask, splitted_absorb, splitted_resist, false, 0, false, true);
2371 }
2372
2373 CleanDamage cleanDamage = CleanDamage(splitted, 0, BASE_ATTACK, MELEE_HIT_NORMAL);
2374 Unit::DealDamage(attacker, caster, splitted, &cleanDamage, DIRECT_DAMAGE, schoolMask, (*itr)->GetSpellInfo(), false);
2375 }
2376
2377 // We're going to call functions which can modify content of the list during iteration over it's elements
2378 // Let's copy the list so we can prevent iterator invalidation
2380 for (AuraEffectList::iterator itr = vSplitDamagePctCopy.begin(), next; (itr != vSplitDamagePctCopy.end()) && (dmgInfo.GetDamage() > 0); ++itr)
2381 {
2382 // Check if aura was removed during iteration - we don't need to work on such auras
2383 AuraApplication const* aurApp = (*itr)->GetBase()->GetApplicationOfTarget(victim->GetGUID());
2384 if (!aurApp)
2385 continue;
2386
2387 // check damage school mask
2388 if (!((*itr)->GetMiscValue() & schoolMask))
2389 continue;
2390
2391 // Damage can be splitted only if aura has an alive caster
2392 Unit* caster = (*itr)->GetCaster();
2393 if (!caster || (caster == victim) || !caster->IsInWorld() || !caster->IsAlive())
2394 continue;
2395
2396 // Xinef: Single Target splits require LoS
2397 SpellInfo const* splitSpellInfo = (*itr)->GetSpellInfo();
2398 if (!splitSpellInfo->Effects[(*itr)->GetEffIndex()].IsAreaAuraEffect() && !splitSpellInfo->HasAttribute(SPELL_ATTR2_IGNORE_LINE_OF_SIGHT))
2399 if (!caster->IsWithinLOSInMap(victim) || !caster->IsWithinDist(victim, splitSpellInfo->GetMaxRange(splitSpellInfo->IsPositive(), caster)))
2400 continue;
2401
2402 uint32 splitDamage = CalculatePct(dmgInfo.GetDamage(), (*itr)->GetAmount());
2403 SpellSchoolMask splitSchoolMask = schoolMask;
2404
2405 (*itr)->GetBase()->CallScriptEffectSplitHandlers(*itr, aurApp, dmgInfo, splitDamage);
2406
2407 // absorb must be smaller than the damage itself
2408 splitDamage = RoundToInterval(splitDamage, uint32(0), uint32(dmgInfo.GetDamage()));
2409
2410 // Roar of Sacrifice, dont absorb it
2411 if (splitSpellInfo->Id != 53480)
2412 dmgInfo.AbsorbDamage(splitDamage);
2413 else
2414 splitSchoolMask = SPELL_SCHOOL_MASK_NATURE;
2415
2416 uint32 splitted = splitDamage;
2417 uint32 splitted_absorb = 0;
2418 uint32 splitted_resist = 0;
2419
2420 uint32 procAttacker = 0, procVictim = 0, procEx = PROC_EX_NORMAL_HIT;
2421 DamageInfo splittedDmgInfo(attacker, caster, splitted, spellInfo, splitSchoolMask, dmgInfo.GetDamageType());
2422 if (caster->IsImmunedToDamageOrSchool(schoolMask))
2423 {
2424 procEx |= PROC_EX_IMMUNE;
2425 splittedDmgInfo.AbsorbDamage(splitted);
2426 }
2427 else
2428 {
2429 Unit::CalcAbsorbResist(splittedDmgInfo, true);
2430 Unit::DealDamageMods(caster, splitted, &splitted_absorb);
2431 }
2432
2433 splitted_absorb = splittedDmgInfo.GetAbsorb();
2434 splitted_resist = splittedDmgInfo.GetResist();
2435 splitted = splittedDmgInfo.GetDamage();
2436
2437 // create procs
2438 createProcFlags(spellInfo, BASE_ATTACK, false, procAttacker, procVictim);
2439 caster->ProcDamageAndSpellFor(true, attacker, procVictim, procEx, BASE_ATTACK, spellInfo, splitted);
2440
2441 if (attacker)
2442 {
2443 attacker->SendSpellNonMeleeDamageLog(caster, splitSpellInfo, splitted, splitSchoolMask, splitted_absorb, splitted_resist, false, 0, false, true);
2444 }
2445
2446 CleanDamage cleanDamage = CleanDamage(splitted, 0, BASE_ATTACK, MELEE_HIT_NORMAL);
2447 Unit::DealDamage(attacker, caster, splitted, &cleanDamage, DIRECT_DAMAGE, splitSchoolMask, splitSpellInfo, false);
2448 }
2449 }
2450}
double rand_norm()
Definition: Random.cpp:77
@ POWER_MANA
Definition: SharedDefines.h:241
@ SPELL_ATTR2_IGNORE_LINE_OF_SIGHT
Definition: SharedDefines.h:430
@ SPELL_ATTR4_NO_CAST_LOG
Definition: SharedDefines.h:502
SpellSchoolMask
Definition: SharedDefines.h:267
@ SPELL_SCHOOL_MASK_NORMAL
Definition: SharedDefines.h:269
@ SPELL_SCHOOL_MASK_NATURE
Definition: SharedDefines.h:272
@ SPELL_SCHOOL_MASK_HOLY
Definition: SharedDefines.h:270
@ SPELL_AURA_MANA_SHIELD
Definition: SpellAuraDefines.h:160
@ SPELL_AURA_MOD_TARGET_ABSORB_SCHOOL
Definition: SpellAuraDefines.h:257
@ SPELL_AURA_MOD_IGNORE_TARGET_RESIST
Definition: SpellAuraDefines.h:332
@ SPELL_AURA_SPLIT_DAMAGE_FLAT
Definition: SpellAuraDefines.h:216
@ SPELL_AURA_MOD_TARGET_ABILITY_ABSORB_SCHOOL
Definition: SpellAuraDefines.h:258
@ SPELL_AURA_SPLIT_DAMAGE_PCT
Definition: SpellAuraDefines.h:144
@ SPELL_AURA_SCHOOL_ABSORB
Definition: SpellAuraDefines.h:132
@ SPELL_AURA_MOD_ABILITY_IGNORE_TARGET_RESIST
Definition: SpellAuraDefines.h:333
@ AURA_REMOVE_BY_ENEMY_SPELL
Definition: SpellAuraDefines.h:394
@ SPELL_ATTR0_CU_BINARY_SPELL
Definition: SpellInfo.h:196
@ SPELL_ATTR0_CU_SCHOOLMASK_NORMAL_WITH_MAGIC
Definition: SpellInfo.h:199
@ PROC_EX_NORMAL_HIT
Definition: SpellMgr.h:194
@ PROC_EX_IMMUNE
Definition: SpellMgr.h:202
void createProcFlags(SpellInfo const *spellInfo, WeaponAttackType attackType, bool positive, uint32 &procAttacker, uint32 &procVictim)
Definition: Unit.cpp:16018
@ MELEE_HIT_NORMAL
Definition: Unit.h:717
@ DIRECT_DAMAGE
Definition: Unit.h:435
T AddPct(T &base, U pct)
Definition: Util.h:67
T RoundToInterval(T &num, T floor, T ceil)
Definition: Util.h:79
T CalculatePct(T base, U pct)
Definition: Util.h:61
Definition: SpellAuraEffects.h:347
Definition: SpellAuraEffects.h:39
SpellInfo const * GetSpellInfo() const
Definition: SpellAuraEffects.h:54
void SetAmount(int32 amount)
Definition: SpellAuraEffects.h:65
Unit * GetCaster() const
Definition: SpellAuraEffects.h:47
int32 GetMiscValue() const
Definition: SpellAuraEffects.cpp:442
Aura * GetBase() const
Definition: SpellAuraEffects.h:49
uint32 GetEffIndex() const
Definition: SpellAuraEffects.h:56
int32 GetAmount() const
Definition: SpellAuraEffects.h:63
void CallScriptEffectAbsorbHandlers(AuraEffect *aurEff, AuraApplication const *aurApp, DamageInfo &dmgInfo, uint32 &absorbAmount, bool &defaultPrevented)
Definition: SpellAuras.cpp:2563
void CallScriptEffectAfterAbsorbHandlers(AuraEffect *aurEff, AuraApplication const *aurApp, DamageInfo &dmgInfo, uint32 &absorbAmount)
Definition: SpellAuras.cpp:2581
void CallScriptEffectManaShieldHandlers(AuraEffect *aurEff, AuraApplication const *aurApp, DamageInfo &dmgInfo, uint32 &absorbAmount, bool &defaultPrevented)
Definition: SpellAuras.cpp:2595
void CallScriptEffectAfterManaShieldHandlers(AuraEffect *aurEff, AuraApplication const *aurApp, DamageInfo &dmgInfo, uint32 &absorbAmount)
Definition: SpellAuras.cpp:2609
virtual void Remove(AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT)=0
void ResistDamage(uint32 amount)
Definition: Unit.cpp:160
void AbsorbDamage(uint32 amount)
Definition: Unit.cpp:153
Unit * GetVictim() const
Definition: Unit.h:790
Unit * GetAttacker() const
Definition: Unit.h:789
SpellInfo const * GetSpellInfo() const
Definition: Unit.h:791
DamageEffectType GetDamageType() const
Definition: Unit.h:793
SpellSchoolMask GetSchoolMask() const
Definition: Unit.h:792
uint32 GetDamage() const
Definition: Unit.h:795
std::array< SpellEffectInfo, MAX_SPELL_EFFECTS > Effects
Definition: SpellInfo.h:391
float GetMaxRange(bool positive=false, Unit *caster=nullptr, Spell *spell=nullptr) const
Definition: SpellInfo.cpp:2303
bool IsPositive() const
Definition: SpellInfo.cpp:1220
int32 ModifyPower(Powers power, int32 val, bool withPowerUpdate=true)
Definition: Unit.cpp:14039
AuraEffectList const & GetAuraEffectsByType(AuraType type) const
Definition: Unit.h:1964
static uint32 CalcArmorReducedDamage(Unit const *attacker, Unit const *victim, const uint32 damage, SpellInfo const *spellInfo, uint8 attackerLevel=0, WeaponAttackType attackType=MAX_ATTACK)
Definition: Unit.cpp:1989
static float GetEffectiveResistChance(Unit const *owner, SpellSchoolMask schoolMask, Unit const *victim)
Definition: Unit.cpp:2071
void SendSpellNonMeleeDamageLog(SpellNonMeleeDamage *log)
Definition: Unit.cpp:6210
void ProcDamageAndSpellFor(bool isVictim, Unit *target, uint32 procFlag, uint32 procExtra, WeaponAttackType attType, SpellInfo const *procSpellInfo, uint32 damage, SpellInfo const *procAura=nullptr, int8 procAuraEffectIndex=-1, Spell const *procSpell=nullptr, DamageInfo *damageInfo=nullptr, HealInfo *healInfo=nullptr, uint32 procPhase=2)
Definition: Unit.cpp:16152
std::list< AuraEffect * > AuraEffectList
Definition: Unit.h:1306
bool IsImmunedToDamageOrSchool(SpellSchoolMask meleeSchoolMask) const
Definition: Unit.cpp:12805
static void CalcAbsorbResist(DamageInfo &dmgInfo, bool Splited=false)
Definition: Unit.cpp:2105
static uint32 DealDamage(Unit *attacker, Unit *victim, uint32 damage, CleanDamage const *cleanDamage=nullptr, DamageEffectType damagetype=DIRECT_DAMAGE, SpellSchoolMask damageSchoolMask=SPELL_SCHOOL_MASK_NORMAL, SpellInfo const *spellProto=nullptr, bool durabilityLoss=true, bool allowGM=false, Spell const *spell=nullptr)
Definition: Unit.cpp:814
bool IsWithinDist(WorldObject const *obj, float dist2compare, bool is3D=true, bool useBoundingRadius=true) const
Definition: Object.cpp:1316
Definition: Unit.h:746

◆ CalcArmorReducedDamage()

uint32 Unit::CalcArmorReducedDamage ( Unit const *  attacker,
Unit const *  victim,
const uint32  damage,
SpellInfo const *  spellInfo,
uint8  attackerLevel = 0,
WeaponAttackType  attackType = MAX_ATTACK 
)
static
1990{
1991 float armor = float(victim->GetArmor());
1992
1993 // Ignore enemy armor by SPELL_AURA_MOD_TARGET_RESISTANCE aura
1994 if (attacker)
1995 {
1996 armor += attacker->GetTotalAuraModifierByMiscMask(SPELL_AURA_MOD_TARGET_RESISTANCE, SPELL_SCHOOL_MASK_NORMAL);
1997
1998 if (spellInfo)
1999 if (Player* modOwner = attacker->GetSpellModOwner())
2000 modOwner->ApplySpellMod(spellInfo->Id, SPELLMOD_IGNORE_ARMOR, armor);
2001
2002 AuraEffectList const& ResIgnoreAurasAb = attacker->GetAuraEffectsByType(SPELL_AURA_MOD_ABILITY_IGNORE_TARGET_RESIST);
2003 for (AuraEffectList::const_iterator j = ResIgnoreAurasAb.begin(); j != ResIgnoreAurasAb.end(); ++j)
2004 {
2005 if ((*j)->GetMiscValue() & SPELL_SCHOOL_MASK_NORMAL
2006 && (*j)->IsAffectedOnSpell(spellInfo))
2007 armor = floor(AddPct(armor, -(*j)->GetAmount()));
2008 }
2009
2010 AuraEffectList const& ResIgnoreAuras = attacker->GetAuraEffectsByType(SPELL_AURA_MOD_IGNORE_TARGET_RESIST);
2011 for (AuraEffectList::const_iterator j = ResIgnoreAuras.begin(); j != ResIgnoreAuras.end(); ++j)
2012 {
2013 if ((*j)->GetMiscValue() & SPELL_SCHOOL_MASK_NORMAL)
2014 armor = floor(AddPct(armor, -(*j)->GetAmount()));
2015 }
2016
2017 // Apply Player CR_ARMOR_PENETRATION rating and buffs from stances\specializations etc.
2018 if (attacker->GetTypeId() == TYPEID_PLAYER)
2019 {
2020 float bonusPct = 0;
2021 AuraEffectList const& armorPenAuras = attacker->GetAuraEffectsByType(SPELL_AURA_MOD_ARMOR_PENETRATION_PCT);
2022 for (AuraEffectList::const_iterator itr = armorPenAuras.begin(); itr != armorPenAuras.end(); ++itr)
2023 {
2024 if ((*itr)->GetSpellInfo()->EquippedItemClass == -1)
2025 {
2026 if (!spellInfo || (*itr)->IsAffectedOnSpell(spellInfo) || (*itr)->GetMiscValue() & spellInfo->GetSchoolMask())
2027 bonusPct += (*itr)->GetAmount();
2028 else if (!(*itr)->GetMiscValue() && !(*itr)->HasSpellClassMask())
2029 bonusPct += (*itr)->GetAmount();
2030 }
2031 else
2032 {
2033 if (attacker->ToPlayer()->HasItemFitToSpellRequirements((*itr)->GetSpellInfo()))
2034 bonusPct += (*itr)->GetAmount();
2035 }
2036 }
2037
2038 float maxArmorPen = 0;
2039 if (victim->getLevel() < 60)
2040 maxArmorPen = float(400 + 85 * victim->getLevel());
2041 else
2042 maxArmorPen = 400 + 85 * victim->getLevel() + 4.5f * 85 * (victim->getLevel() - 59);
2043
2044 // Cap armor penetration to this number
2045 maxArmorPen = std::min((armor + maxArmorPen) / 3, armor);
2046 // Figure out how much armor do we ignore
2047 float armorPen = CalculatePct(maxArmorPen, bonusPct + attacker->ToPlayer()->GetRatingBonusValue(CR_ARMOR_PENETRATION));
2048 // Got the value, apply it
2049 armor -= std::min(armorPen, maxArmorPen);
2050 }
2051 }
2052
2053 if (armor < 0.0f)
2054 armor = 0.0f;
2055
2056 float levelModifier = attacker ? attacker->getLevel() : attackerLevel;
2057 if (levelModifier > 59)
2058 levelModifier = levelModifier + (4.5f * (levelModifier - 59));
2059
2060 float tmpvalue = 0.1f * armor / (8.5f * levelModifier + 40);
2061 tmpvalue = tmpvalue / (1.0f + tmpvalue);
2062
2063 if (tmpvalue < 0.0f)
2064 tmpvalue = 0.0f;
2065 if (tmpvalue > 0.75f)
2066 tmpvalue = 0.75f;
2067
2068 return uint32(std::ceil(std::max(damage * (1.0f - tmpvalue), 0.0f)));
2069}
@ SPELL_AURA_MOD_ARMOR_PENETRATION_PCT
Definition: SpellAuraDefines.h:343
@ SPELL_AURA_MOD_TARGET_RESISTANCE
Definition: SpellAuraDefines.h:186
@ SPELLMOD_IGNORE_ARMOR
Definition: SpellDefines.h:90
@ CR_ARMOR_PENETRATION
Definition: Unit.h:428

◆ CalcHealAbsorb()

void Unit::CalcHealAbsorb ( HealInfo healInfo)
static
2453{
2454 if (!healInfo.GetHeal())
2455 return;
2456
2457 int32 const healing = static_cast<int32>(healInfo.GetHeal());
2458 int32 absorbAmount = 0;
2459
2460 // Need remove expired auras after
2461 bool existExpired = false;
2462
2463 // absorb without mana cost
2465 for (AuraEffectList::const_iterator i = vHealAbsorb.begin(); i != vHealAbsorb.end() && absorbAmount <= healing; ++i)
2466 {
2467 if (!((*i)->GetMiscValue() & healInfo.GetSpellInfo()->SchoolMask))
2468 continue;
2469
2470 // Max Amount can be absorbed by this aura
2471 int32 currentAbsorb = (*i)->GetAmount();
2472
2473 // Found empty aura (impossible but..)
2474 if (currentAbsorb <= 0)
2475 {
2476 existExpired = true;
2477 continue;
2478 }
2479
2480 // currentAbsorb - damage can be absorbed by shield
2481 // If need absorb less damage
2482 if (healing < currentAbsorb + absorbAmount)
2483 currentAbsorb = healing - absorbAmount;
2484
2485 absorbAmount += currentAbsorb;
2486
2487 // Reduce shield amount
2488 (*i)->SetAmount((*i)->GetAmount() - currentAbsorb);
2489 // Need remove it later
2490 if ((*i)->GetAmount() <= 0)
2491 existExpired = true;
2492 }
2493
2494 // Remove all expired absorb auras
2495 if (existExpired)
2496 {
2497 for (AuraEffectList::const_iterator i = vHealAbsorb.begin(); i != vHealAbsorb.end();)
2498 {
2499 AuraEffect* auraEff = *i;
2500 ++i;
2501 if (auraEff->GetAmount() <= 0)
2502 {
2503 uint32 removedAuras = healInfo.GetTarget()->m_removedAurasCount;
2505 if (removedAuras + 1 < healInfo.GetTarget()->m_removedAurasCount)
2506 i = vHealAbsorb.begin();
2507 }
2508 }
2509 }
2510
2511 if (absorbAmount > 0)
2512 healInfo.AbsorbHeal(absorbAmount);
2513}
@ SPELL_AURA_SCHOOL_HEAL_ABSORB
Definition: SpellAuraDefines.h:364
SpellInfo const * GetSpellInfo() const
Definition: Unit.h:834
void AbsorbHeal(uint32 amount)
Definition: Unit.h:818
Unit * GetTarget() const
Definition: Unit.h:831
uint32 GetHeal() const
Definition: Unit.h:832
uint32 SchoolMask
Definition: SpellInfo.h:390

◆ CalcSpellDuration()

int32 Unit::CalcSpellDuration ( SpellInfo const *  spellProto)
14714{
14715 uint8 comboPoints = GetComboPoints();
14716
14717 int32 minduration = spellProto->GetDuration();
14718 int32 maxduration = spellProto->GetMaxDuration();
14719
14720 int32 duration;
14721
14722 if (comboPoints && minduration != -1 && minduration != maxduration)
14723 duration = minduration + int32((maxduration - minduration) * comboPoints / 5);
14724 else
14725 duration = minduration;
14726
14727 return duration;
14728}
uint8 GetComboPoints(Unit const *who=nullptr) const
--------—Combo point system----------------—
Definition: Unit.h:2285

◆ CalculateAOEDamageReduction()

int32 Unit::CalculateAOEDamageReduction ( int32  damage,
uint32  schoolMask,
Unit caster 
) const
20477{
20478 damage = int32(float(damage) * GetTotalAuraMultiplierByMiscMask(SPELL_AURA_MOD_AOE_DAMAGE_AVOIDANCE, schoolMask));
20479 if (caster && caster->GetTypeId() == TYPEID_UNIT)
20481
20482 return damage;
20483}
@ SPELL_AURA_MOD_CREATURE_AOE_DAMAGE_AVOIDANCE
Definition: SpellAuraDefines.h:373
@ SPELL_AURA_MOD_AOE_DAMAGE_AVOIDANCE
Definition: SpellAuraDefines.h:292
float GetTotalAuraMultiplierByMiscMask(AuraType auratype, uint32 misc_mask) const
Definition: Unit.cpp:5874

◆ CalculateDamage()

uint32 Unit::CalculateDamage ( WeaponAttackType  attType,
bool  normalized,
bool  addTotalPct,
uint8  itemDamagesMask = 0 
)
2935{
2936 float minDamage = 0.0f;
2937 float maxDamage = 0.0f;
2938
2939 if (normalized || !addTotalPct || itemDamagesMask)
2940 {
2941 // get both by default
2942 if (!itemDamagesMask)
2943 {
2944 itemDamagesMask = (1 << 0) | (1 << 1);
2945 }
2946
2947 for (uint8 i = 0; i < MAX_ITEM_PROTO_DAMAGES; ++i)
2948 {
2949 if (itemDamagesMask & (1 << i))
2950 {
2951 float minTmp, maxTmp;
2952 CalculateMinMaxDamage(attType, normalized, addTotalPct, minTmp, maxTmp, i);
2953 minDamage += minTmp;
2954 maxDamage += maxTmp;
2955 }
2956 }
2957 }
2958 else
2959 {
2960 switch (attType)
2961 {
2962 case RANGED_ATTACK:
2965 break;
2966 case BASE_ATTACK:
2969 break;
2970 case OFF_ATTACK:
2973 break;
2974 default:
2975 break;
2976 }
2977 }
2978
2979 minDamage = std::max(0.f, minDamage);
2980 maxDamage = std::max(0.f, maxDamage);
2981
2982 if (minDamage > maxDamage)
2983 {
2984 std::swap(minDamage, maxDamage);
2985 }
2986
2987 return urand(uint32(minDamage), uint32(maxDamage));
2988}
uint32 urand(uint32 min, uint32 max)
Definition: Random.cpp:44
@ UNIT_FIELD_MINDAMAGE
Definition: UpdateFields.h:127
@ UNIT_FIELD_MAXDAMAGE
Definition: UpdateFields.h:128
@ UNIT_FIELD_MAXOFFHANDDAMAGE
Definition: UpdateFields.h:130
@ UNIT_FIELD_MAXRANGEDDAMAGE
Definition: UpdateFields.h:169
@ UNIT_FIELD_MINRANGEDDAMAGE
Definition: UpdateFields.h:168
@ UNIT_FIELD_MINOFFHANDDAMAGE
Definition: UpdateFields.h:129
float GetFloatValue(uint16 index) const
Definition: Object.cpp:317
virtual void CalculateMinMaxDamage(WeaponAttackType attType, bool normalized, bool addTotalPct, float &minDamage, float &maxDamage, uint8 damageIndex=0)=0

◆ CalculateDefaultCoefficient()

float Unit::CalculateDefaultCoefficient ( SpellInfo const *  spellInfo,
DamageEffectType  damagetype 
) const
17258{
17259 // Damage over Time spells bonus calculation
17260 float DotFactor = 1.0f;
17261 if (damagetype == DOT)
17262 {
17263 int32 DotDuration = spellInfo->GetDuration();
17264 if (!spellInfo->IsChanneled() && DotDuration > 0)
17265 DotFactor = DotDuration / 15000.0f;
17266
17267 if (uint32 DotTicks = spellInfo->GetMaxTicks())
17268 DotFactor /= DotTicks;
17269 }
17270
17271 int32 CastingTime = spellInfo->IsChanneled() ? spellInfo->GetDuration() : spellInfo->CalcCastTime();
17272 // Distribute Damage over multiple effects, reduce by AoE
17273 CastingTime = GetCastingTimeForBonus(spellInfo, damagetype, CastingTime);
17274
17275 // As wowwiki says: C = (Cast Time / 3.5)
17276 return (CastingTime / 3500.0f) * DotFactor;
17277}
@ DOT
Definition: Unit.h:437
uint32 GetCastingTimeForBonus(SpellInfo const *spellProto, DamageEffectType damagetype, uint32 CastingTime) const
Definition: Unit.cpp:17139

◆ CalculateLevelPenalty()

float Unit::CalculateLevelPenalty ( SpellInfo const *  spellProto) const
2991{
2992 if (GetTypeId() != TYPEID_PLAYER)
2993 return 1.0f;
2994
2995 if (spellProto->SpellLevel <= 0 || spellProto->SpellLevel >= spellProto->MaxLevel)
2996 return 1.0f;
2997
2998 float LvlPenalty = 0.0f;
2999
3000 // xinef: added brackets
3001 if (spellProto->SpellLevel < 20)
3002 LvlPenalty = (20.0f - spellProto->SpellLevel) * 3.75f;
3003
3004 float LvlFactor = (float(spellProto->SpellLevel) + 6.0f) / float(getLevel());
3005 if (LvlFactor > 1.0f)
3006 LvlFactor = 1.0f;
3007
3008 return AddPct(LvlFactor, -LvlPenalty);
3009}
uint8 getLevel() const
Definition: Unit.h:1418

◆ CalculateMeleeDamage()

void Unit::CalculateMeleeDamage ( Unit victim,
CalcDamageInfo damageInfo,
WeaponAttackType  attackType = BASE_ATTACK,
const bool  sittingVictim = false 
)
1461{
1462 damageInfo->attacker = this;
1463 damageInfo->target = victim;
1464
1465 for (uint8 i = 0; i < MAX_ITEM_PROTO_DAMAGES; ++i)
1466 {
1467 damageInfo->damages[i].damageSchoolMask = GetMeleeDamageSchoolMask(attackType, i);
1468 damageInfo->damages[i].damage = 0;
1469 damageInfo->damages[i].absorb = 0;
1470 damageInfo->damages[i].resist = 0;
1471 }
1472
1473 damageInfo->attackType = attackType;
1474 damageInfo->cleanDamage = 0;
1475 damageInfo->blocked_amount = 0;
1476
1477 damageInfo->TargetState = 0;
1478 damageInfo->HitInfo = 0;
1479 damageInfo->procAttacker = PROC_FLAG_NONE;
1480 damageInfo->procVictim = PROC_FLAG_NONE;
1481 damageInfo->procEx = PROC_EX_NONE;
1482 damageInfo->hitOutCome = MELEE_HIT_EVADE;
1483
1484 if (!victim)
1485 return;
1486
1487 if (!IsAlive() || !victim->IsAlive())
1488 return;
1489
1490 // Select HitInfo/procAttacker/procVictim flag based on attack type
1491 switch (attackType)
1492 {
1493 case BASE_ATTACK:
1496 break;
1497 case OFF_ATTACK:
1500 damageInfo->HitInfo = HITINFO_OFFHAND;
1501 break;
1502 default:
1503 return;
1504 }
1505
1506 // School Immune check
1507 uint8 immunedMask = 0;
1508 bool hasNonPhysicalSchoolMask = false;
1509 for (uint8 i = 0; i < MAX_ITEM_PROTO_DAMAGES; ++i)
1510 {
1512 {
1513 immunedMask |= (1 << i);
1515 {
1516 hasNonPhysicalSchoolMask = true;
1517 }
1518 }
1519 }
1520
1521 // School Immune check
1522 if (immunedMask & ((1 << 0) | (1 << 1)))
1523 {
1524 if (hasNonPhysicalSchoolMask || immunedMask == ((1 << 0) | (1 << 1)))
1525 {
1526 damageInfo->HitInfo |= HITINFO_NORMALSWING;
1527 damageInfo->TargetState = VICTIMSTATE_IS_IMMUNE;
1528
1529 damageInfo->procEx |= PROC_EX_IMMUNE;
1530 return;
1531 }
1532 }
1533
1534 for (uint8 i = 0; i < MAX_ITEM_PROTO_DAMAGES; ++i)
1535 {
1536 // only players have secondary weapon damage
1537 if (i > 0 && GetTypeId() != TYPEID_PLAYER)
1538 {
1539 break;
1540 }
1541
1542 if (immunedMask & (1 << i))
1543 {
1544 continue;
1545 }
1546
1547 SpellSchoolMask schoolMask = SpellSchoolMask(damageInfo->damages[i].damageSchoolMask);
1548 bool const addPctMods = (schoolMask & SPELL_SCHOOL_MASK_NORMAL);
1549
1550 uint32 damage = 0;
1551 uint8 itemDamagesMask = (GetTypeId() == TYPEID_PLAYER) ? (1 << i) : 0;
1552
1553 damage += CalculateDamage(damageInfo->attackType, false, addPctMods, itemDamagesMask);
1554 // Add melee damage bonus
1555 damage = MeleeDamageBonusDone(damageInfo->target, damage, damageInfo->attackType, nullptr, schoolMask);
1556 damage = damageInfo->target->MeleeDamageBonusTaken(this, damage, damageInfo->attackType, nullptr, schoolMask);
1557
1558 // Script Hook For CalculateMeleeDamage -- Allow scripts to change the Damage pre class mitigation calculations
1559 sScriptMgr->ModifyMeleeDamage(damageInfo->target, damageInfo->attacker, damage);
1560
1561 // Calculate armor reduction
1563 {
1564 damageInfo->damages[i].damage = Unit::CalcArmorReducedDamage(this, damageInfo->target, damage, nullptr, 0, damageInfo->attackType);
1565 damageInfo->cleanDamage += damage - damageInfo->damages[i].damage;
1566 }
1567 else
1568 {
1569 damageInfo->damages[i].damage = damage;
1570 }
1571 }
1572
1573 damageInfo->hitOutCome = RollMeleeOutcomeAgainst(damageInfo->target, damageInfo->attackType);
1574
1575 // If the victim was a sitting player and we didn't roll a miss, then crit.
1576 if (sittingVictim && damageInfo->hitOutCome != MELEE_HIT_MISS)
1577 {
1578 damageInfo->hitOutCome = MELEE_HIT_CRIT;
1579 }
1580 switch (damageInfo->hitOutCome)
1581 {
1582 case MELEE_HIT_EVADE:
1584 damageInfo->TargetState = VICTIMSTATE_EVADES;
1585 damageInfo->procEx |= PROC_EX_EVADE;
1586
1587 for (uint8 i = 0; i < MAX_ITEM_PROTO_DAMAGES; ++i)
1588 {
1589 damageInfo->damages[i].damage = 0;
1590 }
1591
1592 damageInfo->cleanDamage = 0;
1593 return;
1594 case MELEE_HIT_MISS:
1595 damageInfo->HitInfo |= HITINFO_MISS;
1596 damageInfo->TargetState = VICTIMSTATE_INTACT;
1597 damageInfo->procEx |= PROC_EX_MISS;
1598
1599 for (uint8 i = 0; i < MAX_ITEM_PROTO_DAMAGES; ++i)
1600 {
1601 damageInfo->damages[i].damage = 0;
1602 }
1603 damageInfo->cleanDamage = 0;
1604 break;
1605 case MELEE_HIT_NORMAL:
1606 damageInfo->TargetState = VICTIMSTATE_HIT;
1607 damageInfo->procEx |= PROC_EX_NORMAL_HIT;
1608 break;
1609 case MELEE_HIT_CRIT:
1610 {
1611 damageInfo->HitInfo |= HITINFO_CRITICALHIT;
1612 damageInfo->TargetState = VICTIMSTATE_HIT;
1613
1614 damageInfo->procEx |= PROC_EX_CRITICAL_HIT;
1615 // Crit bonus calc
1616 for (uint8 i = 0; i < MAX_ITEM_PROTO_DAMAGES; ++i)
1617 {
1618 damageInfo->damages[i].damage *= 2;
1619
1620 float mod = 0.0f;
1621 // Apply SPELL_AURA_MOD_ATTACKER_RANGED_CRIT_DAMAGE or SPELL_AURA_MOD_ATTACKER_MELEE_CRIT_DAMAGE
1622 if (damageInfo->attackType == RANGED_ATTACK)
1623 {
1625 }
1626 else
1627 {
1629
1630 // Increase crit damage from SPELL_AURA_MOD_CRIT_DAMAGE_BONUS
1632 }
1633
1634 uint32 crTypeMask = damageInfo->target->GetCreatureTypeMask();
1635
1636 // Increase crit damage from SPELL_AURA_MOD_CRIT_PERCENT_VERSUS
1638 if (mod != 0)
1639 {
1640 AddPct(damageInfo->damages[i].damage, mod);
1641 }
1642 }
1643 break;
1644 }
1645 case MELEE_HIT_PARRY:
1646 damageInfo->TargetState = VICTIMSTATE_PARRY;
1647 damageInfo->procEx |= PROC_EX_PARRY;
1648 damageInfo->cleanDamage = 0;
1649
1650 for (uint8 i = 0; i < MAX_ITEM_PROTO_DAMAGES; ++i)
1651 {
1652 damageInfo->cleanDamage += damageInfo->damages[i].damage;
1653 damageInfo->damages[i].damage = 0;
1654 }
1655 break;
1656 case MELEE_HIT_DODGE:
1657 damageInfo->TargetState = VICTIMSTATE_DODGE;
1658 damageInfo->procEx |= PROC_EX_DODGE;
1659 damageInfo->cleanDamage = 0;
1660
1661 for (uint8 i = 0; i < MAX_ITEM_PROTO_DAMAGES; ++i)
1662 {
1663 damageInfo->cleanDamage += damageInfo->damages[i].damage;
1664 damageInfo->damages[i].damage = 0;
1665 }
1666 break;
1667 case MELEE_HIT_BLOCK:
1668 {
1669 damageInfo->TargetState = VICTIMSTATE_HIT;
1670 damageInfo->HitInfo |= HITINFO_BLOCK;
1671 damageInfo->procEx |= PROC_EX_BLOCK;
1672 damageInfo->blocked_amount = damageInfo->target->GetShieldBlockValue();
1673 // double blocked amount if block is critical
1674 if (damageInfo->target->isBlockCritical())
1675 damageInfo->blocked_amount += damageInfo->blocked_amount;
1676
1677 uint32 remainingBlock = damageInfo->blocked_amount;
1678 uint8 fullBlockMask = 0;
1679 for (uint8 i = 0; i < MAX_ITEM_PROTO_DAMAGES; ++i)
1680 {
1681 if (remainingBlock && remainingBlock >= damageInfo->damages[i].damage)
1682 {
1683 fullBlockMask |= (1 << i);
1684
1685 remainingBlock -= damageInfo->damages[i].damage;
1686 damageInfo->cleanDamage += damageInfo->damages[i].damage;
1687 damageInfo->damages[i].damage = 0;
1688 }
1689 else
1690 {
1691 damageInfo->cleanDamage += remainingBlock;
1692 damageInfo->damages[i].damage -= remainingBlock;
1693 remainingBlock = 0;
1694 }
1695 }
1696
1697 // full block
1698 if (fullBlockMask == ((1 << 0) | (1 << 1)))
1699 {
1700 damageInfo->TargetState = VICTIMSTATE_BLOCKS;
1701 damageInfo->blocked_amount -= remainingBlock;
1702 }
1703 break;
1704 }
1705 case MELEE_HIT_GLANCING:
1706 {
1707 damageInfo->HitInfo |= HITINFO_GLANCING;
1708 damageInfo->TargetState = VICTIMSTATE_HIT;
1709 damageInfo->procEx |= PROC_EX_NORMAL_HIT;
1710 int32 leveldif = int32(victim->getLevel()) - int32(getLevel());
1711 if (leveldif > 3)
1712 leveldif = 3;
1713 float reducePercent = 1 - leveldif * 0.1f;
1714
1715 for (uint8 i = 0; i < MAX_ITEM_PROTO_DAMAGES; ++i)
1716 {
1717 uint32 reducedDamage = uint32(reducePercent * damageInfo->damages[i].damage);
1718 damageInfo->cleanDamage += damageInfo->damages[i].damage - reducedDamage;
1719 damageInfo->damages[i].damage = reducedDamage;
1720 }
1721 break;
1722 }
1723 case MELEE_HIT_CRUSHING:
1724 damageInfo->HitInfo |= HITINFO_CRUSHING;
1725 damageInfo->TargetState = VICTIMSTATE_HIT;
1726 damageInfo->procEx |= PROC_EX_NORMAL_HIT;
1727
1728 // 150% normal damage
1729 for (uint8 i = 0; i < MAX_ITEM_PROTO_DAMAGES; ++i)
1730 {
1731 damageInfo->damages[i].damage += (damageInfo->damages[i].damage / 2);
1732 }
1733 break;
1734 default:
1735 break;
1736 }
1737
1738 // Always apply HITINFO_AFFECTS_VICTIM in case its not a miss
1739 if (!(damageInfo->HitInfo & HITINFO_MISS))
1740 damageInfo->HitInfo |= HITINFO_AFFECTS_VICTIM;
1741
1742 uint32 tmpHitInfo[MAX_ITEM_PROTO_DAMAGES] = { };
1743
1744 for (uint8 i = 0; i < MAX_ITEM_PROTO_DAMAGES; ++i)
1745 {
1746 int32 dmg = damageInfo->damages[i].damage;
1747 int32 cleanDamage = damageInfo->cleanDamage;
1748 // attackType is checked already for BASE_ATTACK or OFF_ATTACK so it can't be RANGED_ATTACK here
1749 if (CanApplyResilience())
1750 {
1751 int32 resilienceReduction = damageInfo->damages[i].damage;
1752 Unit::ApplyResilience(victim, nullptr, &resilienceReduction, (damageInfo->hitOutCome == MELEE_HIT_CRIT), CR_CRIT_TAKEN_MELEE);
1753
1754 resilienceReduction = damageInfo->damages[i].damage - resilienceReduction;
1755 dmg -= resilienceReduction;
1756 cleanDamage += resilienceReduction;
1757 }
1758
1759 damageInfo->damages[i].damage = std::max(0, dmg);
1760 damageInfo->cleanDamage = std::max(0, cleanDamage);
1761
1762 // Calculate absorb resist
1763 if (damageInfo->damages[i].damage > 0)
1764 {
1765 damageInfo->procVictim |= PROC_FLAG_TAKEN_DAMAGE;
1766
1767 // Calculate absorb & resists
1768 DamageInfo dmgInfo(*damageInfo, i);
1769 Unit::CalcAbsorbResist(dmgInfo);
1770 damageInfo->damages[i].absorb = dmgInfo.GetAbsorb();
1771 damageInfo->damages[i].resist = dmgInfo.GetResist();
1772
1773 if (damageInfo->damages[i].absorb)
1774 {
1775 tmpHitInfo[i] |= (damageInfo->damages[i].damage - damageInfo->damages[i].absorb == 0 ? HITINFO_FULL_ABSORB : HITINFO_PARTIAL_ABSORB);
1776 }
1777
1778 if (damageInfo->damages[i].resist)
1779 {
1780 tmpHitInfo[i] |= (damageInfo->damages[i].damage - damageInfo->damages[i].resist == 0 ? HITINFO_FULL_RESIST : HITINFO_PARTIAL_RESIST);
1781 }
1782
1783 damageInfo->damages[i].damage = dmgInfo.GetDamage();
1784 }
1785 }
1786
1787 // set proper HitInfo flags
1788 if ((tmpHitInfo[0] & HITINFO_FULL_ABSORB) != 0)
1789 {
1790 // set partial absorb when secondary damage isn't full absorbed
1791 damageInfo->HitInfo |= ((tmpHitInfo[1] & HITINFO_PARTIAL_ABSORB) != 0) ? HITINFO_PARTIAL_ABSORB : HITINFO_FULL_ABSORB;
1792 }
1793 else
1794 {
1795 damageInfo->HitInfo |= (tmpHitInfo[0] & HITINFO_PARTIAL_ABSORB);
1796 }
1797
1798 if ((tmpHitInfo[0] & HITINFO_FULL_RESIST) != 0)
1799 {
1800 // set partial resist when secondary damage isn't full resisted
1801 damageInfo->HitInfo |= ((tmpHitInfo[1] & HITINFO_PARTIAL_RESIST) != 0) ? HITINFO_PARTIAL_RESIST : HITINFO_FULL_RESIST;
1802 }
1803 else
1804 {
1805 damageInfo->HitInfo |= (tmpHitInfo[0] & HITINFO_PARTIAL_RESIST);
1806 }
1807}
@ SPELL_AURA_MOD_CRIT_PERCENT_VERSUS
Definition: SpellAuraDefines.h:232
@ SPELL_AURA_MOD_ATTACKER_RANGED_CRIT_DAMAGE
Definition: SpellAuraDefines.h:267
@ SPELL_AURA_MOD_CRIT_DAMAGE_BONUS
Definition: SpellAuraDefines.h:226
@ SPELL_AURA_MOD_ATTACKER_MELEE_CRIT_DAMAGE
Definition: SpellAuraDefines.h:266
@ PROC_EX_NONE
Definition: SpellMgr.h:193
@ PROC_EX_DODGE
Definition: SpellMgr.h:198
@ PROC_EX_BLOCK
Definition: SpellMgr.h:200
@ PROC_EX_CRITICAL_HIT
Definition: SpellMgr.h:195
@ PROC_EX_MISS
Definition: SpellMgr.h:196
@ PROC_EX_PARRY
Definition: SpellMgr.h:199
@ PROC_EX_EVADE
Definition: SpellMgr.h:201
@ PROC_FLAG_DONE_MELEE_AUTO_ATTACK
Definition: SpellMgr.h:110
@ PROC_FLAG_DONE_MAINHAND_ATTACK
Definition: SpellMgr.h:140
@ PROC_FLAG_TAKEN_DAMAGE
Definition: SpellMgr.h:137
@ PROC_FLAG_TAKEN_MELEE_AUTO_ATTACK
Definition: SpellMgr.h:111
@ PROC_FLAG_DONE_OFFHAND_ATTACK
Definition: SpellMgr.h:141
@ PROC_FLAG_NONE
Definition: SpellMgr.h:105
@ VICTIMSTATE_INTACT
Definition: Unit.h:166
@ VICTIMSTATE_HIT
Definition: Unit.h:167
@ VICTIMSTATE_DODGE
Definition: Unit.h:168
@ VICTIMSTATE_IS_IMMUNE
Definition: Unit.h:173
@ VICTIMSTATE_PARRY
Definition: Unit.h:169
@ VICTIMSTATE_BLOCKS
Definition: Unit.h:171
@ VICTIMSTATE_EVADES
Definition: Unit.h:172
@ HITINFO_PARTIAL_ABSORB
Definition: Unit.h:186
@ HITINFO_FULL_RESIST
Definition: Unit.h:187
@ HITINFO_NORMALSWING
Definition: Unit.h:179
@ HITINFO_BLOCK
Definition: Unit.h:193
@ HITINFO_CRUSHING
Definition: Unit.h:197
@ HITINFO_SWINGNOHITSOUND
Definition: Unit.h:201
@ HITINFO_MISS
Definition: Unit.h:184
@ HITINFO_FULL_ABSORB
Definition: Unit.h:185
@ HITINFO_OFFHAND
Definition: Unit.h:182
@ HITINFO_GLANCING
Definition: Unit.h:196
@ HITINFO_CRITICALHIT
Definition: Unit.h:189
@ HITINFO_PARTIAL_RESIST
Definition: Unit.h:188
@ HITINFO_AFFECTS_VICTIM
Definition: Unit.h:181
@ MELEE_HIT_CRUSHING
Definition: Unit.h:717
@ MELEE_HIT_BLOCK
Definition: Unit.h:716
@ MELEE_HIT_CRIT
Definition: Unit.h:717
@ MELEE_HIT_EVADE
Definition: Unit.h:716
@ MELEE_HIT_DODGE
Definition: Unit.h:716
@ MELEE_HIT_MISS
Definition: Unit.h:716
@ MELEE_HIT_PARRY
Definition: Unit.h:716
@ MELEE_HIT_GLANCING
Definition: Unit.h:717
bool isBlockCritical()
Definition: Unit.cpp:3068
uint32 MeleeDamageBonusTaken(Unit *attacker, uint32 pdamage, WeaponAttackType attType, SpellInfo const *spellProto=nullptr, SpellSchoolMask damageSchoolMask=SPELL_SCHOOL_MASK_NORMAL)
Definition: Unit.cpp:13180
virtual SpellSchoolMask GetMeleeDamageSchoolMask(WeaponAttackType attackType=BASE_ATTACK, uint8 damageIndex=0) const =0
int32 GetTotalAuraModifierByMiscMask(AuraType auratype, uint32 misc_mask) const
Definition: Unit.cpp:5861
bool CanApplyResilience() const
Definition: Unit.h:2422
uint32 CalculateDamage(WeaponAttackType attType, bool normalized, bool addTotalPct, uint8 itemDamagesMask=0)
Definition: Unit.cpp:2934
virtual uint32 GetShieldBlockValue() const =0
static void ApplyResilience(Unit const *victim, float *crit, int32 *damage, bool isCrit, CombatRating type)
Definition: Unit.cpp:18959
static bool IsDamageReducedByArmor(SpellSchoolMask damageSchoolMask, SpellInfo const *spellInfo=nullptr, uint8 effIndex=MAX_SPELL_EFFECTS)
Definition: Unit.cpp:1966
int32 GetTotalAuraModifier(AuraType auratype) const
Definition: Unit.cpp:5810
MeleeHitOutcome RollMeleeOutcomeAgainst(Unit const *victim, WeaponAttackType attType) const
Definition: Unit.cpp:2731
uint32 GetCreatureTypeMask() const
Definition: Unit.h:1526
uint32 MeleeDamageBonusDone(Unit *pVictim, uint32 damage, WeaponAttackType attType, SpellInfo const *spellProto=nullptr, SpellSchoolMask damageSchoolMask=SPELL_SCHOOL_MASK_NORMAL)
Definition: Unit.cpp:12978
uint32 damageSchoolMask
Definition: Unit.h:888
uint32 blocked_amount
Definition: Unit.h:894
MeleeHitOutcome hitOutCome
Definition: Unit.h:903
uint32 cleanDamage
Definition: Unit.h:902
uint32 TargetState
Definition: Unit.h:896
uint32 resist
Definition: Unit.h:891
uint32 HitInfo
Definition: Unit.h:895

◆ CalculateMinMaxDamage()

virtual void Unit::CalculateMinMaxDamage ( WeaponAttackType  attType,
bool  normalized,
bool  addTotalPct,
float &  minDamage,
float &  maxDamage,
uint8  damageIndex = 0 
)
pure virtual

Implemented in Creature, and Player.

◆ CalculateSpellDamage()

int32 Unit::CalculateSpellDamage ( Unit const *  target,
SpellInfo const *  spellProto,
uint8  effect_index,
int32 const *  basePoints = nullptr 
) const
14709{
14710 return spellProto->Effects[effect_index].CalcValue(this, basePoints, target);
14711}

◆ CalculateSpellDamageTaken()

void Unit::CalculateSpellDamageTaken ( SpellNonMeleeDamage damageInfo,
int32  damage,
SpellInfo const *  spellInfo,
WeaponAttackType  attackType = BASE_ATTACK,
bool  crit = false 
)
1297{
1298 if (damage < 0)
1299 return;
1300
1301 Unit* victim = damageInfo->target;
1302 if (!victim || !victim->IsAlive())
1303 return;
1304
1305 SpellSchoolMask damageSchoolMask = SpellSchoolMask(damageInfo->schoolMask);
1306 uint32 crTypeMask = victim->GetCreatureTypeMask();
1307
1308 // Script Hook For CalculateSpellDamageTaken -- Allow scripts to change the Damage post class mitigation calculations
1309 sScriptMgr->ModifySpellDamageTaken(damageInfo->target, damageInfo->attacker, damage, spellInfo);
1310
1311 int32 cleanDamage = 0;
1312 if (Unit::IsDamageReducedByArmor(damageSchoolMask, spellInfo))
1313 {
1314 int32 oldDamage = damage;
1315 damage = Unit::CalcArmorReducedDamage(this, victim, damage, spellInfo, 0, attackType);
1316 cleanDamage = oldDamage - damage;
1317 }
1318
1319 bool blocked = false;
1320 // Per-school calc
1321 switch (spellInfo->DmgClass)
1322 {
1323 // Melee and Ranged Spells
1326 {
1327 // Physical Damage
1328 if (damageSchoolMask & SPELL_SCHOOL_MASK_NORMAL)
1329 {
1330 // Get blocked status
1331 blocked = isSpellBlocked(victim, spellInfo, attackType);
1332 }
1333
1334 if (crit)
1335 {
1336 damageInfo->HitInfo |= SPELL_HIT_TYPE_CRIT;
1337
1338 // Calculate crit bonus
1339 uint32 crit_bonus = damage;
1340 // Apply crit_damage bonus for melee spells
1341 if (Player* modOwner = GetSpellModOwner())
1342 modOwner->ApplySpellMod(spellInfo->Id, SPELLMOD_CRIT_DAMAGE_BONUS, crit_bonus);
1343 damage += crit_bonus;
1344
1345 // Apply SPELL_AURA_MOD_ATTACKER_RANGED_CRIT_DAMAGE or SPELL_AURA_MOD_ATTACKER_MELEE_CRIT_DAMAGE
1346 float critPctDamageMod = 0.0f;
1347 if (attackType == RANGED_ATTACK)
1349 else
1351
1352 // Increase crit damage from SPELL_AURA_MOD_CRIT_DAMAGE_BONUS
1353 critPctDamageMod += GetTotalAuraModifierByMiscMask(SPELL_AURA_MOD_CRIT_DAMAGE_BONUS, spellInfo->GetSchoolMask());
1354
1355 // Increase crit damage from SPELL_AURA_MOD_CRIT_PERCENT_VERSUS
1357
1358 if (critPctDamageMod != 0)
1359 AddPct(damage, critPctDamageMod);
1360 }
1361
1362 // Spell weapon based damage CAN BE crit & blocked at same time
1363 if (blocked)
1364 {
1365 damageInfo->blocked = victim->GetShieldBlockValue();
1366 // double blocked amount if block is critical
1367 if (victim->isBlockCritical())
1368 damageInfo->blocked *= 2;
1369 if (damage < int32(damageInfo->blocked))
1370 damageInfo->blocked = uint32(damage);
1371
1372 damage -= damageInfo->blocked;
1373 cleanDamage += damageInfo->blocked;
1374 }
1375
1376 int32 resilienceReduction = damage;
1377 if (CanApplyResilience())
1378 {
1379 if (attackType != RANGED_ATTACK)
1380 {
1381 Unit::ApplyResilience(victim, nullptr, &resilienceReduction, crit, CR_CRIT_TAKEN_MELEE);
1382 }
1383 else
1384 {
1385 Unit::ApplyResilience(victim, nullptr, &resilienceReduction, crit, CR_CRIT_TAKEN_RANGED);
1386 }
1387 }
1388
1389 resilienceReduction = damage - resilienceReduction;
1390 damage -= resilienceReduction;
1391 cleanDamage += resilienceReduction;
1392 break;
1393 }
1394 // Magical Attacks
1397 {
1398 // If crit add critical bonus
1399 if (crit)
1400 {
1401 damageInfo->HitInfo |= SPELL_HIT_TYPE_CRIT;
1402 damage = Unit::SpellCriticalDamageBonus(this, spellInfo, damage, victim);
1403 }
1404
1405 int32 resilienceReduction = damage;
1406 if (CanApplyResilience())
1407 {
1408 Unit::ApplyResilience(victim, nullptr, &resilienceReduction, crit, CR_CRIT_TAKEN_SPELL);
1409 }
1410
1411 resilienceReduction = damage - resilienceReduction;
1412 damage -= resilienceReduction;
1413 cleanDamage += resilienceReduction;
1414 break;
1415 }
1416 default:
1417 break;
1418 }
1419
1420 damageInfo->cleanDamage = std::max(0, cleanDamage);
1421 damageInfo->damage = std::max(0, damage);
1422
1423 // Calculate absorb resist
1424 if (damageInfo->damage > 0)
1425 {
1426 DamageInfo dmgInfo(*damageInfo, SPELL_DIRECT_DAMAGE);
1427 Unit::CalcAbsorbResist(dmgInfo);
1428 damageInfo->absorb = dmgInfo.GetAbsorb();
1429 damageInfo->resist = dmgInfo.GetResist();
1430 damageInfo->damage = dmgInfo.GetDamage();
1431 }
1432}
@ SPELL_DAMAGE_CLASS_RANGED
Definition: SharedDefines.h:1520
@ SPELL_DAMAGE_CLASS_MAGIC
Definition: SharedDefines.h:1518
@ SPELL_DAMAGE_CLASS_NONE
Definition: SharedDefines.h:1517
@ SPELL_DAMAGE_CLASS_MELEE
Definition: SharedDefines.h:1519
@ SPELL_HIT_TYPE_CRIT
Definition: SharedDefines.h:1508
@ SPELLMOD_CRIT_DAMAGE_BONUS
Definition: SpellDefines.h:92
@ SPELL_DIRECT_DAMAGE
Definition: Unit.h:436
bool isSpellBlocked(Unit *victim, SpellInfo const *spellProto, WeaponAttackType attackType=BASE_ATTACK)
Definition: Unit.cpp:3042
static uint32 SpellCriticalDamageBonus(Unit const *caster, SpellInfo const *spellProto, uint32 damage, Unit const *victim)
Definition: Unit.cpp:12192
Unit * target
Definition: Unit.h:914
uint32 HitInfo
Definition: Unit.h:925
uint32 damage
Definition: Unit.h:917
uint32 absorb
Definition: Unit.h:920
Unit * attacker
Definition: Unit.h:915
uint32 schoolMask
Definition: Unit.h:919
uint32 cleanDamage
Definition: Unit.h:927
uint32 resist
Definition: Unit.h:921
uint32 blocked
Definition: Unit.h:924

◆ CanApplyResilience()

bool Unit::CanApplyResilience ( ) const
inline
2422{ return m_applyResilience; }

◆ CanDualWield()

bool Unit::CanDualWield ( ) const
inline
1345{ return m_canDualWield; }

◆ CanEnterWater()

virtual bool Unit::CanEnterWater ( ) const
pure virtual

Implemented in Creature, and Player.

◆ CanFly()

virtual bool Unit::CanFly ( ) const
pure virtual

Implemented in Creature, and Player.

◆ CanFreeMove()

bool Unit::CanFreeMove ( ) const
inline
1402 {
1405 }
@ UNIT_STATE_DISTRACTED
Definition: Unit.h:337
@ UNIT_STATE_CONFUSED
Definition: Unit.h:336
@ UNIT_STATE_FLEEING
Definition: Unit.h:332
@ UNIT_STATE_IN_FLIGHT
Definition: Unit.h:333
@ UNIT_STATE_STUNNED
Definition: Unit.h:328

◆ CanHaveThreatList()

bool Unit::CanHaveThreatList ( ) const
14485{
14486 // only creatures can have threat list
14487 if (GetTypeId() != TYPEID_UNIT)
14488 return false;
14489
14490 // only alive units can have threat list
14491 if (!IsAlive() || isDying())
14492 return false;
14493
14494 // totems can not have threat list
14495 if (ToCreature()->IsTotem())
14496 return false;
14497
14498 // vehicles can not have threat list
14499 if (ToCreature()->IsVehicle() && GetMap()->IsBattlegroundOrArena())
14500 return false;
14501
14502 // summons can not have a threat list, unless they are controlled by a creature
14504 return false;
14505
14506 return true;
14507}
@ UNIT_MASK_CONTROLABLE_GUARDIAN
Definition: Unit.h:683
@ UNIT_MASK_GUARDIAN
Definition: Unit.h:677
bool IsPlayer() const
Definition: Object.h:194
bool IsVehicle() const
Definition: Unit.h:1416
bool isDying() const
Definition: Unit.h:1806
Map * GetMap() const
Definition: Object.h:517

◆ CanInstantCast()

bool Unit::CanInstantCast ( ) const
inline
2432{ return _instantCast; }

◆ CanModifyStats()

bool Unit::CanModifyStats ( ) const
inline
2102{ return m_canModifyStats; }

◆ CanProc()

bool Unit::CanProc ( )
inline
2315{return !m_procDeep;}

◆ CanRestoreMana()

bool Unit::CanRestoreMana ( SpellInfo const *  spellInfo) const
21221{
21222 // Aura of Despair exceptions
21223 switch (spellInfo->Id)
21224 {
21225 case 30824: // Shamanistic Rage
21226 case 31786: // Spiritual Attunement
21227 case 31930: // Judgements of the Wise
21228 case 34075: // Aspect of the Viper
21229 case 34720: // Thrill of the hunt
21230 case 47755: // Rapture
21231 case 63337: // Saronite Vapors (regenerate mana)
21232 case 63375: // Improved stormstrike
21233 case 64372: // Lifebloom
21234 return true;
21235 case 54428: // Divine Plea - only with talent Guarded by the Light
21236 return HasSpell(53583);
21237 default:
21238 break;
21239 }
21240
21241 return false;
21242}
virtual bool HasSpell(uint32) const
Definition: Unit.h:1699

◆ CanSwim()

bool Unit::CanSwim ( ) const
virtual

this method checks the current flag of a unit

These flags can be set within the database or dynamically changed at runtime UNIT_FLAG_SWIMMING must be updated when a unit enters a swimmable area

Reimplemented in Creature.

19975{
19976 // Mirror client behavior, if this method returns false then client will not use swimming animation and for players will apply gravity as if there was no water
19978 return false;
19979 if (HasUnitFlag(UNIT_FLAG_POSSESSED)) // is player
19980 return true;
19982 return false;
19984 return true;
19986}
@ UNIT_FLAG2_UNUSED_6
Definition: Unit.h:506
@ UNIT_FLAG_CANNOT_SWIM
Definition: Unit.h:462
@ UNIT_FLAG_POSSESSED
Definition: Unit.h:472
@ UNIT_FLAG_SWIMMING
Definition: Unit.h:463
@ UNIT_FLAG_RENAME
Definition: Unit.h:452
@ UNIT_FLAG_PET_IN_COMBAT
Definition: Unit.h:459
bool HasUnitFlag2(UnitFlags2 flags) const
Definition: Unit.h:1484

◆ CanUseAttackType()

bool Unit::CanUseAttackType ( uint8  attacktype) const
inline
1605 {
1606 switch (attacktype)
1607 {
1608 case BASE_ATTACK:
1610 case OFF_ATTACK:
1612 case RANGED_ATTACK:
1614 }
1615 return true;
1616 }
@ UNIT_FLAG2_DISARM_OFFHAND
Definition: Unit.h:495
@ UNIT_FLAG2_DISARM_RANGED
Definition: Unit.h:497
@ UNIT_FLAG_DISARMED
Definition: Unit.h:469

◆ CastCustomSpell() [1/4]

SpellCastResult Unit::CastCustomSpell ( uint32  spellId,
CustomSpellValues const &  value,
Unit victim = nullptr,
TriggerCastFlags  triggerFlags = TRIGGERED_NONE,
Item castItem = nullptr,
AuraEffect const *  triggeredByAura = nullptr,
ObjectGuid  originalCaster = ObjectGuid::Empty 
)
1252{
1253 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId);
1254 if (!spellInfo)
1255 {
1256 LOG_ERROR("entities.unit", "CastSpell: unknown spell {} by caster {}", spellId, GetGUID().ToString());
1258 }
1259
1260 SpellCastTargets targets;
1261 targets.SetUnitTarget(victim);
1262
1263 return CastSpell(targets, spellInfo, &value, triggerFlags, castItem, triggeredByAura, originalCaster);
1264}
#define LOG_ERROR(filterType__,...)
Definition: Log.h:159
@ SPELL_FAILED_SPELL_UNAVAILABLE
Definition: SharedDefines.h:1028
Definition: Spell.h:109
void SetUnitTarget(Unit *target)
Definition: Spell.cpp:233

◆ CastCustomSpell() [2/4]

SpellCastResult Unit::CastCustomSpell ( uint32  spellId,
SpellValueMod  mod,
int32  value,
Unit victim,
bool  triggered,
Item castItem = nullptr,
AuraEffect const *  triggeredByAura = nullptr,
ObjectGuid  originalCaster = ObjectGuid::Empty 
)
1238{
1239 CustomSpellValues values;
1240 values.AddSpellMod(mod, value);
1241 return CastCustomSpell(spellId, values, target, triggered ? TRIGGERED_FULL_MASK : TRIGGERED_NONE, castItem, triggeredByAura, originalCaster);
1242}
@ TRIGGERED_NONE
Definition: SpellDefines.h:131
Definition: SpellDefines.h:162
void AddSpellMod(SpellValueMod mod, int32 value)
Definition: SpellDefines.h:164
SpellCastResult CastCustomSpell(Unit *victim, uint32 spellId, int32 const *bp0, int32 const *bp1, int32 const *bp2, bool triggered, Item *castItem=nullptr, AuraEffect const *triggeredByAura=nullptr, ObjectGuid originalCaster=ObjectGuid::Empty)
Definition: Unit.cpp:1225

◆ CastCustomSpell() [3/4]

SpellCastResult Unit::CastCustomSpell ( uint32  spellId,
SpellValueMod  mod,
int32  value,
Unit victim = nullptr,
TriggerCastFlags  triggerFlags = TRIGGERED_NONE,
Item castItem = nullptr,
AuraEffect const *  triggeredByAura = nullptr,
ObjectGuid  originalCaster = ObjectGuid::Empty 
)
1245{
1246 CustomSpellValues values;
1247 values.AddSpellMod(mod, value);
1248 return CastCustomSpell(spellId, values, target, triggerFlags, castItem, triggeredByAura, originalCaster);
1249}

◆ CastCustomSpell() [4/4]

SpellCastResult Unit::CastCustomSpell ( Unit victim,
uint32  spellId,
int32 const *  bp0,
int32 const *  bp1,
int32 const *  bp2,
bool  triggered,
Item castItem = nullptr,
AuraEffect const *  triggeredByAura = nullptr,
ObjectGuid  originalCaster = ObjectGuid::Empty 
)
1226{
1227 CustomSpellValues values;
1228 if (bp0)
1229 values.AddSpellMod(SPELLVALUE_BASE_POINT0, *bp0);
1230 if (bp1)
1231 values.AddSpellMod(SPELLVALUE_BASE_POINT1, *bp1);
1232 if (bp2)
1233 values.AddSpellMod(SPELLVALUE_BASE_POINT2, *bp2);
1234 return CastCustomSpell(spellId, values, target, triggered ? TRIGGERED_FULL_MASK : TRIGGERED_NONE, castItem, triggeredByAura, originalCaster);
1235}
@ SPELLVALUE_BASE_POINT1
Definition: SpellDefines.h:115
@ SPELLVALUE_BASE_POINT2
Definition: SpellDefines.h:116
@ SPELLVALUE_BASE_POINT0
Definition: SpellDefines.h:114

◆ CastDelayedSpellWithPeriodicAmount()

void Unit::CastDelayedSpellWithPeriodicAmount ( Unit caster,
uint32  spellId,
AuraType  auraType,
int32  addAmount,
uint8  effectIndex = 0 
)
20298{
20299 for (AuraEffectList::iterator i = m_modAuras[auraType].begin(); i != m_modAuras[auraType].end(); ++i)
20300 {
20301 AuraEffect* aurEff = *i;
20302 if (aurEff->GetCasterGUID() != caster->GetGUID() || aurEff->GetId() != spellId || aurEff->GetEffIndex() != effectIndex || !aurEff->GetTotalTicks())
20303 continue;
20304
20305 addAmount += ((aurEff->GetOldAmount() * std::max<int32>(aurEff->GetTotalTicks() - int32(aurEff->GetTickNumber()), 0)) / aurEff->GetTotalTicks());
20306 break;
20307 }
20308
20309 // xinef: delay only for casting on different unit
20310 if (this == caster)
20311 caster->CastCustomSpell(spellId, SPELLVALUE_BASE_POINT0, addAmount, this, TriggerCastFlags(TRIGGERED_FULL_MASK & ~TRIGGERED_NO_PERIODIC_RESET), nullptr, nullptr, caster->GetGUID());
20312 else
20313 caster->m_Events.AddEvent(new AuraMunchingQueue(*caster, GetGUID(), addAmount, spellId), caster->m_Events.CalculateQueueTime(400));
20314}
TriggerCastFlags
Definition: SpellDefines.h:130
@ TRIGGERED_NO_PERIODIC_RESET
Will ignore equipped item requirements.
Definition: SpellDefines.h:150
uint32 GetTickNumber() const
Definition: SpellAuraEffects.h:86
int32 GetOldAmount() const
Definition: SpellAuraEffects.h:115
uint32 GetId() const
Definition: SpellAuraEffects.cpp:432
int32 GetTotalTicks() const
Definition: SpellAuraEffects.cpp:7004
ObjectGuid GetCasterGUID() const
Definition: SpellAuraEffects.h:48
Definition: Unit.cpp:20277
uint64 CalculateQueueTime(uint64 delay) const
Definition: EventProcessor.cpp:141

◆ CastPetAura()

void Unit::CastPetAura ( PetAura const *  aura)
17372{
17373 uint32 auraId = aura->GetAura(GetEntry());
17374 if (!auraId)
17375 return;
17376
17377 if (auraId == 35696) // Demonic Knowledge
17378 {
17379 int32 basePoints = aura->GetDamage();
17380 CastCustomSpell(this, auraId, &basePoints, nullptr, nullptr, true);
17381 }
17382 else
17383 CastSpell(this, auraId, true);
17384}

◆ CastSpell() [1/7]

SpellCastResult Unit::CastSpell ( float  x,
float  y,
float  z,
uint32  spellId,
bool  triggered,
Item castItem = nullptr,
AuraEffect const *  triggeredByAura = nullptr,
ObjectGuid  originalCaster = ObjectGuid::Empty 
)
1267{
1268 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId);
1269 if (!spellInfo)
1270 {
1271 LOG_ERROR("entities.unit", "CastSpell: unknown spell {} by caster {}", spellId, GetGUID().ToString());
1273 }
1274
1275 SpellCastTargets targets;
1276 targets.SetDst(x, y, z, GetOrientation());
1277
1278 return CastSpell(targets, spellInfo, nullptr, triggered ? TRIGGERED_FULL_MASK : TRIGGERED_NONE, castItem, triggeredByAura, originalCaster);
1279}
void SetDst(float x, float y, float z, float orientation, uint32 mapId=MAPID_INVALID)
Definition: Spell.cpp:400

◆ CastSpell() [2/7]

SpellCastResult Unit::CastSpell ( GameObject go,
uint32  spellId,
bool  triggered,
Item castItem = nullptr,
AuraEffect triggeredByAura = nullptr,
ObjectGuid  originalCaster = ObjectGuid::Empty 
)
1282{
1283 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId);
1284 if (!spellInfo)
1285 {
1286 LOG_ERROR("entities.unit", "CastSpell: unknown spell {} by caster {}", spellId, GetGUID().ToString());
1288 }
1289
1290 SpellCastTargets targets;
1291 targets.SetGOTarget(go);
1292
1293 return CastSpell(targets, spellInfo, nullptr, triggered ? TRIGGERED_FULL_MASK : TRIGGERED_NONE, castItem, triggeredByAura, originalCaster);
1294}
void SetGOTarget(GameObject *target)
Definition: Spell.cpp:265

◆ CastSpell() [3/7]

SpellCastResult Unit::CastSpell ( SpellCastTargets const &  targets,
SpellInfo const *  spellInfo,
CustomSpellValues const *  value,
TriggerCastFlags  triggerFlags = TRIGGERED_NONE,
Item castItem = nullptr,
AuraEffect const *  triggeredByAura = nullptr,
ObjectGuid  originalCaster = ObjectGuid::Empty 
)
1169{
1170 if (!spellInfo)
1171 {
1172 LOG_ERROR("entities.unit", "CastSpell: unknown spell by caster {}", GetGUID().ToString());
1174 }
1175
1176 // TODO: this is a workaround - not needed anymore, but required for some scripts :(
1177 if (!originalCaster && triggeredByAura)
1178 {
1179 originalCaster = triggeredByAura->GetCasterGUID();
1180 }
1181
1182 Spell* spell = new Spell(this, spellInfo, triggerFlags, originalCaster);
1183
1184 if (value)
1185 {
1186 for (CustomSpellValues::const_iterator itr = value->begin(); itr != value->end(); ++itr)
1187 {
1188 spell->SetSpellValue(itr->first, itr->second);
1189 }
1190 }
1191
1192 spell->m_CastItem = castItem;
1193 return spell->prepare(&targets, triggeredByAura);
1194}
void SetSpellValue(SpellValueMod mod, int32 value)
Definition: Spell.cpp:8380
Item * m_CastItem
Definition: Spell.h:521

◆ CastSpell() [4/7]

SpellCastResult Unit::CastSpell ( Unit victim,
SpellInfo const *  spellInfo,
bool  triggered,
Item castItem = nullptr,
AuraEffect const *  triggeredByAura = nullptr,
ObjectGuid  originalCaster = ObjectGuid::Empty 
)
1214{
1215 return CastSpell(victim, spellInfo, triggered ? TRIGGERED_FULL_MASK : TRIGGERED_NONE, castItem, triggeredByAura, originalCaster);
1216}

◆ CastSpell() [5/7]

SpellCastResult Unit::CastSpell ( Unit victim,
SpellInfo const *  spellInfo,
TriggerCastFlags  triggerFlags = TRIGGERED_NONE,
Item castItem = nullptr,
AuraEffect const *  triggeredByAura = nullptr,
ObjectGuid  originalCaster = ObjectGuid::Empty 
)
1219{
1220 SpellCastTargets targets;
1221 targets.SetUnitTarget(victim);
1222 return CastSpell(targets, spellInfo, nullptr, triggerFlags, castItem, triggeredByAura, originalCaster);
1223}

◆ CastSpell() [6/7]

SpellCastResult Unit::CastSpell ( Unit victim,
uint32  spellId,
bool  triggered,
Item castItem = nullptr,
AuraEffect const *  triggeredByAura = nullptr,
ObjectGuid  originalCaster = ObjectGuid::Empty 
)
1197{
1198 return CastSpell(victim, spellId, triggered ? TRIGGERED_FULL_MASK : TRIGGERED_NONE, castItem, triggeredByAura, originalCaster);
1199}

◆ CastSpell() [7/7]

SpellCastResult Unit::CastSpell ( Unit victim,
uint32  spellId,
TriggerCastFlags  triggerFlags = TRIGGERED_NONE,
Item castItem = nullptr,
AuraEffect const *  triggeredByAura = nullptr,
ObjectGuid  originalCaster = ObjectGuid::Empty 
)
1202{
1203 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId);
1204 if (!spellInfo)
1205 {
1206 LOG_ERROR("entities.unit", "CastSpell: unknown spell {} by caster {}", spellId, GetGUID().ToString());
1208 }
1209
1210 return CastSpell(victim, spellInfo, triggerFlags, castItem, triggeredByAura, originalCaster);
1211}

◆ CastStop()

void Unit::CastStop ( uint32  except_spellid = 0,
bool  withInstant = true 
)
1162{
1164 if (m_currentSpells[i] && m_currentSpells[i]->m_spellInfo->Id != except_spellid)
1165 InterruptSpell(CurrentSpellTypes(i), false, withInstant);
1166}
#define CURRENT_FIRST_NON_MELEE_SPELL
Definition: Unit.h:984
CurrentSpellTypes
Definition: Unit.h:977

◆ ChangeSeat()

void Unit::ChangeSeat ( int8  seatId,
bool  next = true 
)
19731{
19732 if (!m_vehicle)
19733 return;
19734
19735 if (seatId < 0)
19736 {
19737 seatId = m_vehicle->GetNextEmptySeat(GetTransSeat(), next);
19738 if (seatId < 0)
19739 return;
19740 }
19741 else if (seatId == GetTransSeat() || !m_vehicle->HasEmptySeat(seatId))
19742 return;
19743
19745 if (!m_vehicle->AddPassenger(this, seatId))
19746 ABORT();
19747}
int8 GetNextEmptySeat(int8 seatId, bool next) const
Definition: Vehicle.cpp:235
bool HasEmptySeat(int8 seatId) const
Definition: Vehicle.cpp:218

◆ CleanupBeforeRemoveFromMap()

void Unit::CleanupBeforeRemoveFromMap ( bool  finalCleanup)
15580{
15582 return;
15583
15584 // This needs to be before RemoveFromWorld to make GetCaster() return a valid pointer on aura removal
15586
15587 if (IsInWorld()) // not in world and not being removed atm
15589
15590 ASSERT(GetGUID());
15591
15592 // A unit may be in removelist and not in world, but it is still in grid
15593 // and may have some references during delete
15596
15597 if (finalCleanup)
15598 m_cleanupDone = true;
15599
15600 m_Events.KillAllEvents(false); // non-delatable (currently casted spells) will not deleted now but it will deleted at call in Map::RemoveAllObjectsInRemoveList
15601 CombatStop();
15606 GetMotionMaster()->Clear(false); // remove different non-standard movement generators.
15607}
void KillAllEvents(bool force)
Definition: EventProcessor.cpp:82
void deleteReferences(bool removeFromMap=false)
Definition: HostileRefMgr.cpp:125
void Clear(bool reset=true)
Definition: MotionMaster.h:165
void ClearAllThreat()
Definition: ThreatMgr.cpp:418
void CombatStop(bool includingCast=false)
Definition: Unit.cpp:10389
void RemoveAllGameObjects()
Definition: Unit.cpp:6163
void ClearComboPoints()
Definition: Unit.cpp:16925
void ClearComboPointHolders()
Definition: Unit.cpp:16980
HostileRefMgr & getHostileRefMgr()
Definition: Unit.h:2146
void RemoveFromWorld() override
Definition: Unit.cpp:15533
void RemoveAllAuras()
Definition: Unit.cpp:5227
ThreatMgr & GetThreatMgr()
Definition: Unit.h:2142

◆ CleanupsBeforeDelete()

void Unit::CleanupsBeforeDelete ( bool  finalCleanup = true)
overridevirtual

Reimplemented from WorldObject.

15610{
15611 if (GetTransport())
15612 {
15614 SetTransport(nullptr);
15617 }
15618
15619 CleanupBeforeRemoveFromMap(finalCleanup);
15620}
virtual void RemovePassenger(WorldObject *passenger, bool withAll=false)=0
void CleanupBeforeRemoveFromMap(bool finalCleanup)
Definition: Unit.cpp:15579
void SetTransport(Transport *t)
Definition: Object.h:593
void Reset()
Definition: Object.h:275
void RemoveMovementFlag(uint32 flag)
Definition: Object.h:321

◆ ClearAllReactives()

void Unit::ClearAllReactives ( )
16989{
16990 for (uint8 i = 0; i < MAX_REACTIVE; ++i)
16991 m_reactiveTimer[i] = 0;
16992
16999}
@ CLASS_HUNTER
Definition: SharedDefines.h:115
@ CLASS_WARRIOR
Definition: SharedDefines.h:113
@ AURA_STATE_DEFENSE
Definition: SharedDefines.h:1264
@ AURA_STATE_HUNTER_PARRY
Definition: SharedDefines.h:1270
uint8 getClass() const
Definition: Unit.h:1424
bool HasAuraState(AuraStateType flag, SpellInfo const *spellProto=nullptr, Unit const *Caster=nullptr) const
Definition: Unit.cpp:10495

◆ ClearComboPointHolders()

void Unit::ClearComboPointHolders ( )
16981{
16982 while (!m_ComboPointHolders.empty())
16983 {
16984 (*m_ComboPointHolders.begin())->ClearComboPoints(); // this also removes it from m_comboPointHolders
16985 }
16986}

◆ ClearComboPoints()

void Unit::ClearComboPoints ( )
16926{
16927 if (!m_comboTarget)
16928 {
16929 return;
16930 }
16931
16932 // remove Premed-like effects
16933 // (NB: this Aura retains the CP while it's active - now that CP have reset, it shouldn't be there anymore)
16935
16936 m_comboPoints = 0;
16939 m_comboTarget = nullptr;
16940}
@ SPELL_AURA_RETAIN_COMBO_POINTS
Definition: SpellAuraDefines.h:211

◆ ClearDiminishings()

void Unit::ClearDiminishings ( )
inline
1332{ m_Diminishing.clear(); }

◆ ClearInCombat()

void Unit::ClearInCombat ( )
13703{
13704 m_CombatTimer = 0;
13706
13707 // Player's state will be cleared in Player::UpdateContestedPvP
13708 if (Creature* creature = ToCreature())
13709 {
13710 if (creature->GetCreatureTemplate() && creature->GetCreatureTemplate()->unit_flags & UNIT_FLAG_IMMUNE_TO_PC)
13711 SetImmuneToPC(true); // set immunity state to the one from db on evade
13712
13715 ReplaceAllDynamicFlags(creature->GetCreatureTemplate()->dynamicflags);
13716
13717 creature->SetAssistanceTimer(0);
13718
13719 // Xinef: will be recalculated at follow movement generator initialization
13720 if (!IsPet() && !IsCharmed())
13721 return;
13722 }
13723 else if (Player* player = ToPlayer())
13724 {
13725 player->UpdatePotionCooldown();
13726 if (player->getClass() == CLASS_DEATH_KNIGHT)
13727 for (uint8 i = 0; i < MAX_RUNES; ++i)
13728 player->SetGracePeriod(i, 0);
13729 }
13730
13731 if (Player* player = this->ToPlayer())
13732 {
13733 sScriptMgr->OnPlayerLeaveCombat(player);
13734 }
13735}
#define MAX_RUNES
Definition: Player.h:399
@ CLASS_DEATH_KNIGHT
Definition: SharedDefines.h:118
@ UNIT_STATE_ATTACK_PLAYER
Definition: Unit.h:339
@ UNIT_FLAG_IN_COMBAT
Definition: Unit.h:467
@ UNIT_FLAG_IMMUNE_TO_PC
Definition: Unit.h:456
void ReplaceAllDynamicFlags(uint32 flag) override
Definition: Unit.h:1326
bool IsCharmed() const
Definition: Unit.h:1868
bool IsPet() const
Definition: Unit.h:1413
void SetImmuneToPC(bool apply, bool keepCombat=false)
Definition: Unit.cpp:13511
void RemoveUnitFlag(UnitFlags flags)
Definition: Unit.h:1480

◆ ClearInPetCombat()

void Unit::ClearInPetCombat ( )
13738{
13741 if (Unit* owner = GetOwner())
13742 {
13743 owner->RemoveUnitFlag(UNIT_FLAG_PET_IN_COMBAT);
13744 }
13745}
@ AURA_INTERRUPT_FLAG_LEAVE_COMBAT
Definition: SpellDefines.h:70

◆ ClearUnitState()

void Unit::ClearUnitState ( uint32  f)
inline
1399{ m_state &= ~f; }

◆ CombatStart()

void Unit::CombatStart ( Unit target,
bool  initialAggro = true 
)
13530{
13531 // Xinef: Dont allow to start combat with triggers
13532 if (victim->GetTypeId() == TYPEID_UNIT && victim->ToCreature()->IsTrigger())
13533 return;
13534
13535 if (initialAggro)
13536 {
13537 // Make player victim stand up automatically
13538 if (victim->getStandState() && victim->IsPlayer())
13539 {
13540 victim->SetStandState(UNIT_STAND_STATE_STAND);
13541 }
13542
13543 if (!victim->IsInCombat() && victim->GetTypeId() != TYPEID_PLAYER && !victim->ToCreature()->HasReactState(REACT_PASSIVE) && victim->ToCreature()->IsAIEnabled)
13544 {
13545 if (victim->IsPet())
13546 victim->ToCreature()->AI()->AttackedBy(this); // PetAI has special handler before AttackStart()
13547 else
13548 {
13549 victim->ToCreature()->AI()->AttackStart(this);
13550 // if the target is an NPC with a pet or minion, pet should react.
13551 if (Unit* victimControlledUnit = victim->GetFirstControlled())
13552 {
13553 victimControlledUnit->SetInCombatWith(this);
13554 SetInCombatWith(victimControlledUnit);
13555 victimControlledUnit->AddThreat(this, 0.0f);
13556 }
13557 }
13558
13559 // if unit has an owner, put owner in combat.
13560 if (Unit* victimOwner = victim->GetOwner())
13561 {
13562 if (!(victimOwner->IsInCombatWith(this)))
13563 {
13564 /* warding off to not take over aggro for no reason
13565 Using only AddThreat causes delay in attack */
13566 if (!victimOwner->IsInCombat() && victimOwner->IsAIEnabled)
13567 {
13568 victimOwner->ToCreature()->AI()->AttackStart(this);
13569 }
13570 victimOwner->SetInCombatWith(this);
13571 SetInCombatWith(victimOwner);
13572 victimOwner->AddThreat(this, 0.0f);
13573 }
13574 }
13575 }
13576
13577 SetInCombatWith(victim);
13578 victim->SetInCombatWith(this);
13579
13580 // Xinef: If pet started combat - put owner in combat
13581 if (Unit* owner = GetOwner())
13582 {
13583 owner->SetInCombatWith(victim);
13584 victim->SetInCombatWith(owner);
13585 }
13586 }
13587
13588 Unit* who = victim->GetCharmerOrOwnerOrSelf();
13589 if (who->GetTypeId() == TYPEID_PLAYER)
13590 SetContestedPvP(who->ToPlayer());
13591
13593 if (player && who->IsPvP() && (who->GetTypeId() != TYPEID_PLAYER || !player->duel || player->duel->Opponent != who))
13594 {
13595 player->UpdatePvP(true);
13597 }
13598}
@ AURA_INTERRUPT_FLAG_ENTER_PVP_COMBAT
Definition: SpellDefines.h:67
@ REACT_PASSIVE
Definition: Unit.h:1023
@ UNIT_STAND_STATE_STAND
Definition: Unit.h:53
void UpdatePvP(bool state, bool _override=false)
Definition: PlayerUpdates.cpp:1481
Unit * GetCharmerOrOwnerOrSelf() const
Definition: Unit.h:1845
void SetContestedPvP(Player *attackedPlayer=nullptr, bool lookForNearContestedGuards=true)
Definition: Unit.cpp:17309
bool IsPvP() const
Definition: Unit.h:1515
Unit * GetFirstControlled() const
Definition: Unit.cpp:11023

◆ CombatStartOnCast()

void Unit::CombatStartOnCast ( Unit target,
bool  initialAggro = true,
uint32  duration = 0 
)
13601{
13602 // Xinef: Dont allow to start combat with triggers
13603 if (target->GetTypeId() == TYPEID_UNIT && target->ToCreature()->IsTrigger())
13604 return;
13605
13606 if (initialAggro)
13607 {
13608 SetInCombatWith(target, duration);
13609
13610 // Xinef: If pet started combat - put owner in combat
13611 if (Unit* owner = GetOwner())
13612 owner->SetInCombatWith(target, duration);
13613 }
13614
13615 Unit* who = target->GetCharmerOrOwnerOrSelf();
13616 if (who->GetTypeId() == TYPEID_PLAYER)
13617 SetContestedPvP(who->ToPlayer());
13618
13620 if (player && who->IsPvP() && (who->GetTypeId() != TYPEID_PLAYER || !player->duel || player->duel->Opponent != who))
13621 {
13622 player->UpdatePvP(true);
13624 }
13625}
bool IsTrigger() const
Definition: Creature.h:76

◆ CombatStop()

void Unit::CombatStop ( bool  includingCast = false)
10390{
10391 if (includingCast && IsNonMeleeSpellCast(false))
10393
10394 AttackStop();
10396 if (GetTypeId() == TYPEID_PLAYER)
10397 ToPlayer()->SendAttackSwingCancelAttack(); // melee and ranged forced attack cancel
10398 ClearInCombat();
10399
10400 // xinef: just in case
10403}
void SendAttackSwingCancelAttack()
Definition: PlayerMisc.cpp:140
bool IsPetInCombat() const
Definition: Unit.h:1688
void ClearInPetCombat()
Definition: Unit.cpp:13737
void RemoveAllAttackers()
Definition: Unit.cpp:10432
void ClearInCombat()
Definition: Unit.cpp:13702
bool AttackStop()
Definition: Unit.cpp:10356

◆ CombatStopWithPets()

void Unit::CombatStopWithPets ( bool  includingCast = false)
10406{
10407 CombatStop(includingCast);
10408
10409 for (ControlSet::const_iterator itr = m_Controlled.begin(); itr != m_Controlled.end(); ++itr)
10410 (*itr)->CombatStop(includingCast);
10411}

◆ CountPctFromCurHealth()

uint32 Unit::CountPctFromCurHealth ( int32  pct) const
inline
1448{ return CalculatePct(GetHealth(), pct); }
uint32 GetHealth() const
Definition: Unit.h:1438

◆ CountPctFromMaxHealth()

uint32 Unit::CountPctFromMaxHealth ( int32  pct) const
inline
1447{ return CalculatePct(GetMaxHealth(), pct); }
uint32 GetMaxHealth() const
Definition: Unit.h:1439

◆ CreateTamedPetFrom() [1/2]

Pet * Unit::CreateTamedPetFrom ( Creature creatureTarget,
uint32  spell_id = 0 
)
17402{
17403 if (GetTypeId() != TYPEID_PLAYER)
17404 return nullptr;
17405
17406 Pet* pet = new Pet(ToPlayer(), HUNTER_PET);
17407
17408 if (!pet->CreateBaseAtCreature(creatureTarget))
17409 {
17410 delete pet;
17411 return nullptr;
17412 }
17413
17414 uint8 level = creatureTarget->getLevel() + 5 < getLevel() ? (getLevel() - 5) : creatureTarget->getLevel();
17415
17416 if (!InitTamedPet(pet, level, spell_id))
17417 {
17418 delete pet;
17419 return nullptr;
17420 }
17421
17422 return pet;
17423}
@ HUNTER_PET
Definition: PetDefines.h:32
bool CreateBaseAtCreature(Creature *creature)
Definition: Pet.cpp:932
bool InitTamedPet(Pet *pet, uint8 level, uint32 spell_id)
Definition: Unit.cpp:17445

◆ CreateTamedPetFrom() [2/2]

Pet * Unit::CreateTamedPetFrom ( uint32  creatureEntry,
uint32  spell_id = 0 
)
17426{
17427 if (GetTypeId() != TYPEID_PLAYER)
17428 return nullptr;
17429
17430 CreatureTemplate const* creatureInfo = sObjectMgr->GetCreatureTemplate(creatureEntry);
17431 if (!creatureInfo)
17432 return nullptr;
17433
17434 Pet* pet = new Pet(ToPlayer(), HUNTER_PET);
17435
17436 if (!pet->CreateBaseAtCreatureInfo(creatureInfo, this) || !InitTamedPet(pet, getLevel(), spell_id))
17437 {
17438 delete pet;
17439 return nullptr;
17440 }
17441
17442 return pet;
17443}
bool CreateBaseAtCreatureInfo(CreatureTemplate const *cinfo, Unit *owner)
Definition: Pet.cpp:967

◆ CreateVehicleKit()

bool Unit::CreateVehicleKit ( uint32  id,
uint32  creatureEntry 
)
18748{
18749 VehicleEntry const* vehInfo = sVehicleStore.LookupEntry(id);
18750 if (!vehInfo)
18751 return false;
18752
18753 m_vehicleKit = new Vehicle(this, vehInfo, creatureEntry);
18756 return true;
18757}
DBCStorage< VehicleEntry > sVehicleStore(VehicleEntryfmt)
@ UNIT_MASK_VEHICLE
Definition: Unit.h:680
@ UPDATEFLAG_VEHICLE
Definition: UpdateData.h:46
Definition: DBCStructure.h:1989

◆ DealDamage()

uint32 Unit::DealDamage ( Unit attacker,
Unit victim,
uint32  damage,
CleanDamage const *  cleanDamage = nullptr,
DamageEffectType  damagetype = DIRECT_DAMAGE,
SpellSchoolMask  damageSchoolMask = SPELL_SCHOOL_MASK_NORMAL,
SpellInfo const *  spellProto = nullptr,
bool  durabilityLoss = true,
bool  allowGM = false,
Spell const *  spell = nullptr 
)
static
815{
816 // Xinef: initialize damage done for rage calculations
817 // Xinef: its rare to modify damage in hooks, however training dummy's sets damage to 0
818 uint32 rage_damage = damage + ((cleanDamage != nullptr) ? cleanDamage->absorbed_damage : 0);
819
820 //if (attacker)
821 {
822 if (victim->IsAIEnabled)
823 victim->GetAI()->DamageTaken(attacker, damage, damagetype, damageSchoolMask);
824
825 if (attacker && attacker->IsAIEnabled)
826 attacker->GetAI()->DamageDealt(victim, damage, damagetype);
827 }
828
829 // Hook for OnDamage Event
830 sScriptMgr->OnDamage(attacker, victim, damage);
831
832 if (victim->GetTypeId() == TYPEID_PLAYER && attacker != victim)
833 {
834 // Signal to pets that their owner was attacked
835 Pet* pet = victim->ToPlayer()->GetPet();
836
837 if (pet && pet->IsAlive())
838 pet->AI()->OwnerAttackedBy(attacker);
839 }
840
841 //Dont deal damage to unit if .cheat god is enable.
842 if (victim->GetTypeId() == TYPEID_PLAYER)
843 {
844 if (victim->ToPlayer()->GetCommandStatus(CHEAT_GOD))
845 {
846 return 0;
847 }
848 }
849
850 // Signal the pet it was attacked so the AI can respond if needed
851 if (victim->GetTypeId() == TYPEID_UNIT && attacker != victim && victim->IsPet() && victim->IsAlive())
852 victim->ToPet()->AI()->AttackedBy(attacker);
853
854 if (damagetype != NODAMAGE)
855 {
856 // interrupting auras with AURA_INTERRUPT_FLAG_DAMAGE before checking !damage (absorbed damage breaks that type of auras)
857 if (spellProto)
858 {
859 if (!spellProto->HasAttribute(SPELL_ATTR4_REACTIVE_DAMAGE_PROC))
861 }
862 else
864
865 // interrupt spells with SPELL_INTERRUPT_FLAG_ABORT_ON_DMG on absorbed damage (no dots)
866 if (!damage && damagetype != DOT && cleanDamage && cleanDamage->absorbed_damage)
867 {
868 if (victim != attacker && victim->GetTypeId() == TYPEID_PLAYER)
869 {
870 if (Spell* spell = victim->m_currentSpells[CURRENT_GENERIC_SPELL])
871 {
872 if (spell->getState() == SPELL_STATE_PREPARING)
873 {
874 uint32 interruptFlags = spell->m_spellInfo->InterruptFlags;
875 if (interruptFlags & SPELL_INTERRUPT_FLAG_ABORT_ON_DMG)
876 {
877 victim->InterruptNonMeleeSpells(false);
878 }
879 }
880 }
881 }
882 }
883
884 // We're going to call functions which can modify content of the list during iteration over it's elements
885 // Let's copy the list so we can prevent iterator invalidation
887 // copy damage to casters of this aura
888 for (AuraEffectList::iterator i = vCopyDamageCopy.begin(); i != vCopyDamageCopy.end(); ++i)
889 {
890 // Check if aura was removed during iteration - we don't need to work on such auras
891 if (!((*i)->GetBase()->IsAppliedOnTarget(victim->GetGUID())))
892 continue;
893 // check damage school mask
894 if (((*i)->GetMiscValue() & damageSchoolMask) == 0)
895 continue;
896
897 Unit* shareDamageTarget = (*i)->GetCaster();
898 if (!shareDamageTarget)
899 continue;
900 SpellInfo const* spell = (*i)->GetSpellInfo();
901
902 uint32 shareDamage = CalculatePct(damage, (*i)->GetAmount());
903
904 uint32 shareAbsorb = 0;
905 uint32 shareResist = 0;
906
907 if (shareDamageTarget->IsImmunedToDamageOrSchool(damageSchoolMask))
908 {
909 shareAbsorb = shareDamage;
910 shareDamage = 0;
911 }
912 else
913 {
914 DamageInfo sharedDamageInfo(attacker, shareDamageTarget, shareDamage, spellProto, damageSchoolMask, damagetype);
915 Unit::CalcAbsorbResist(sharedDamageInfo, true);
916 shareAbsorb = sharedDamageInfo.GetAbsorb();
917 shareResist = sharedDamageInfo.GetResist();
918 shareDamage = sharedDamageInfo.GetDamage();
919 Unit::DealDamageMods(shareDamageTarget, shareDamage, &shareAbsorb);
920 }
921
922 if (attacker && shareDamageTarget->GetTypeId() == TYPEID_PLAYER)
923 {
924 attacker->SendSpellNonMeleeDamageLog(shareDamageTarget, spell, shareDamage, damageSchoolMask, shareAbsorb, shareResist, damagetype == DIRECT_DAMAGE, 0, false, true);
925 }
926
927 Unit::DealDamage(attacker, shareDamageTarget, shareDamage, cleanDamage, NODAMAGE, damageSchoolMask, spellProto, false, false, damageSpell);
928 }
929 }
930
931 // Rage from Damage made (only from direct weapon damage)
932 if (attacker && cleanDamage && damagetype == DIRECT_DAMAGE && attacker != victim && attacker->getPowerType() == POWER_RAGE)
933 {
934 uint32 weaponSpeedHitFactor;
935
936 switch (cleanDamage->attackType)
937 {
938 case BASE_ATTACK:
939 case OFF_ATTACK:
940 {
941 weaponSpeedHitFactor = uint32(attacker->GetAttackTime(cleanDamage->attackType) / 1000.0f * (cleanDamage->attackType == BASE_ATTACK ? 3.5f : 1.75f));
942 if (cleanDamage->hitOutCome == MELEE_HIT_CRIT)
943 weaponSpeedHitFactor *= 2;
944
945 attacker->RewardRage(rage_damage, weaponSpeedHitFactor, true);
946 break;
947 }
948 case RANGED_ATTACK:
949 break;
950 default:
951 break;
952 }
953 }
954
955 if (!damage)
956 {
957 // Rage from absorbed damage
958 if (cleanDamage && cleanDamage->absorbed_damage)
959 {
960 if (victim->getPowerType() == POWER_RAGE)
961 victim->RewardRage(cleanDamage->absorbed_damage, 0, false);
962
963 if (attacker && attacker->getPowerType() == POWER_RAGE )
964 attacker->RewardRage(cleanDamage->absorbed_damage, 0, true);
965 }
966
967 return 0;
968 }
969
970 LOG_DEBUG("entities.unit", "DealDamageStart");
971
972 uint32 health = victim->GetHealth();
973 LOG_DEBUG("entities.unit", "deal dmg:{} to health:{} ", damage, health);
974
975 // duel ends when player has 1 or less hp
976 bool duel_hasEnded = false;
977 bool duel_wasMounted = false;
978 if (victim->GetTypeId() == TYPEID_PLAYER && victim->ToPlayer()->duel && damage >= (health - 1))
979 {
980 // xinef: situation not possible earlier, just return silently.
981 if (!attacker)
982 return 0;
983
984 // prevent kill only if killed in duel and killed by opponent or opponent controlled creature
985 if (victim->ToPlayer()->duel->Opponent == attacker || victim->ToPlayer()->duel->Opponent->GetGUID() == attacker->GetOwnerGUID())
986 damage = health - 1;
987
988 duel_hasEnded = true;
989 }
990 else if (victim->IsVehicle() && damage >= (health - 1) && victim->GetCharmer() && victim->GetCharmer()->GetTypeId() == TYPEID_PLAYER)
991 {
992 Player* victimRider = victim->GetCharmer()->ToPlayer();
993
994 if (victimRider && victimRider->duel && victimRider->duel->IsMounted)
995 {
996 // xinef: situation not possible earlier, just return silently.
997 if (!attacker)
998 return 0;
999
1000 // prevent kill only if killed in duel and killed by opponent or opponent controlled creature
1001 if (victimRider->duel->Opponent == attacker || victimRider->duel->Opponent->GetGUID() == attacker->GetCharmerGUID())
1002 damage = health - 1;
1003
1004 duel_wasMounted = true;
1005 duel_hasEnded = true;
1006 }
1007 }
1008
1009 if (attacker && attacker != victim)
1010 if (Player* killer = attacker->GetCharmerOrOwnerPlayerOrPlayerItself())
1011 {
1012 // pussywizard: don't allow GMs to deal damage in normal way (this leaves no evidence in logs!), they have commands to do so
1013 //if (!allowGM && killer->GetSession()->GetSecurity() && killer->GetSession()->GetSecurity() <= SEC_ADMINISTRATOR)
1014 // return 0;
1015
1016 if (Battleground* bg = killer->GetBattleground())
1017 {
1018 bg->UpdatePlayerScore(killer, SCORE_DAMAGE_DONE, damage);
1019 killer->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_DAMAGE_DONE, damage, 0, victim); // pussywizard: InBattleground() optimization
1020 }
1021 //killer->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_HIT_DEALT, damage); // pussywizard: optimization
1022 }
1023
1024 if (victim->GetTypeId() == TYPEID_PLAYER)
1025 ;//victim->ToPlayer()->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_HIT_RECEIVED, damage); // pussywizard: optimization
1026 else if (!victim->IsControlledByPlayer() || victim->IsVehicle())
1027 {
1028 if (!victim->ToCreature()->hasLootRecipient())
1029 victim->ToCreature()->SetLootRecipient(attacker);
1030
1031 if (!attacker || attacker->IsControlledByPlayer() || attacker->IsCreatedByPlayer())
1032 {
1033 uint32 unDamage = health < damage ? health : damage;
1034 bool damagedByPlayer = unDamage && attacker && attacker->m_movedByPlayer != nullptr;
1035 victim->ToCreature()->LowerPlayerDamageReq(unDamage, damagedByPlayer);
1036 }
1037 }
1038
1039 if (health <= damage)
1040 {
1041 LOG_DEBUG("entities.unit", "DealDamage: victim just died");
1042
1043 //if (attacker && victim->GetTypeId() == TYPEID_PLAYER && victim != attacker)
1044 //victim->ToPlayer()->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_TOTAL_DAMAGE_RECEIVED, health); // pussywizard: optimization
1045 Unit::Kill(attacker, victim, durabilityLoss, cleanDamage ? cleanDamage->attackType : BASE_ATTACK, spellProto, damageSpell);
1046 }
1047 else
1048 {
1049 LOG_DEBUG("entities.unit", "DealDamageAlive");
1050
1051 //if (victim->GetTypeId() == TYPEID_PLAYER)
1052 // victim->ToPlayer()->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_TOTAL_DAMAGE_RECEIVED, damage); // pussywizard: optimization
1053
1054 victim->ModifyHealth(- (int32)damage);
1055
1056 if (damagetype == DIRECT_DAMAGE || damagetype == SPELL_DIRECT_DAMAGE)
1057 victim->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_DIRECT_DAMAGE, spellProto ? spellProto->Id : 0);
1058
1059 if (victim->GetTypeId() != TYPEID_PLAYER)
1060 {
1061 // Part of Evade mechanics. DoT's and Thorns / Retribution Aura do not contribute to this
1062 if (damagetype != DOT && damage > 0 && !victim->GetOwnerGUID().IsPlayer() && (!spellProto || !spellProto->HasAura(SPELL_AURA_DAMAGE_SHIELD)))
1064
1065 if (attacker)
1066 {
1067 if (spellProto && !victim->IsInCombatWith(attacker))
1068 {
1069 victim->CombatStart(attacker, !(spellProto->AttributesEx3 & SPELL_ATTR3_SUPRESS_TARGET_PROCS));
1070 }
1071
1072 victim->AddThreat(attacker, float(damage), damageSchoolMask, spellProto);
1073 }
1074 }
1075 else // victim is a player
1076 {
1077 // random durability for items (HIT TAKEN)
1079 {
1082 }
1083 }
1084
1085 // Rage from damage received
1086 if (attacker != victim && victim->getPowerType() == POWER_RAGE)
1087 {
1088 uint32 rageDamage = damage + (cleanDamage ? cleanDamage->absorbed_damage : 0);
1089 victim->RewardRage(rageDamage, 0, false);
1090 }
1091
1092 if (attacker && attacker->GetTypeId() == TYPEID_PLAYER)
1093 {
1094 // random durability for items (HIT DONE)
1096 {
1098 attacker->ToPlayer()->DurabilityPointLossForEquipSlot(slot);
1099 }
1100 }
1101
1102 if (damagetype != NODAMAGE && damage && (!spellProto || !(spellProto->HasAttribute(SPELL_ATTR3_TREAT_AS_PERIODIC) || spellProto->HasAttribute(SPELL_ATTR7_DONT_CAUSE_SPELL_PUSHBACK))))
1103 {
1104 if (victim != attacker && victim->GetTypeId() == TYPEID_PLAYER) // does not support creature push_back
1105 {
1106 if (damagetype != DOT && !(damageSpell && damageSpell->m_targets.HasDstChannel()))
1107 {
1108 if (Spell* spell = victim->m_currentSpells[CURRENT_GENERIC_SPELL])
1109 {
1110 if (spell->getState() == SPELL_STATE_PREPARING)
1111 {
1112 uint32 interruptFlags = spell->m_spellInfo->InterruptFlags;
1113 if (interruptFlags & SPELL_INTERRUPT_FLAG_ABORT_ON_DMG)
1114 {
1115 victim->InterruptNonMeleeSpells(false);
1116 }
1117 else if (interruptFlags & SPELL_INTERRUPT_FLAG_PUSH_BACK)
1118 {
1119 spell->Delayed();
1120 }
1121 }
1122 }
1123
1124 if (Spell* spell = victim->m_currentSpells[CURRENT_CHANNELED_SPELL])
1125 if (spell->getState() == SPELL_STATE_CASTING)
1126 {
1127 if ((spell->m_spellInfo->ChannelInterruptFlags & CHANNEL_FLAG_DELAY) != 0)
1128 {
1129 spell->DelayedChannel();
1130 }
1131 }
1132 }
1133 }
1134 }
1135
1136 // last damage from duel opponent
1137 if (duel_hasEnded)
1138 {
1139 Player* he = duel_wasMounted ? victim->GetCharmer()->ToPlayer() : victim->ToPlayer();
1140
1141 ASSERT_NODEBUGINFO(he && he->duel);
1142
1143 if (duel_wasMounted) // In this case victim==mount
1144 victim->SetHealth(1);
1145 else
1146 he->SetHealth(1);
1147
1148 he->duel->Opponent->CombatStopWithPets(true);
1149 he->CombatStopWithPets(true);
1150
1151 he->CastSpell(he, 7267, true); // beg
1153 }
1154 }
1155
1156 LOG_DEBUG("entities.unit", "DealDamageEnd returned {} damage", damage);
1157
1158 return damage;
1159}
@ SCORE_DAMAGE_DONE
Definition: BattlegroundScore.h:33
#define MAX_AGGRO_RESET_TIME
Definition: CreatureData.h:32
@ ACHIEVEMENT_CRITERIA_TYPE_DAMAGE_DONE
Definition: DBCEnums.h:136
#define ASSERT_NODEBUGINFO
Definition: Errors.h:69
@ RATE_DURABILITY_LOSS_DAMAGE
Definition: IWorld.h:500
@ CHEAT_GOD
Definition: Player.h:991
EquipmentSlots
Definition: Player.h:674
@ EQUIPMENT_SLOT_END
Definition: Player.h:695
bool roll_chance_f(float chance)
Definition: Random.h:53
@ POWER_RAGE
Definition: SharedDefines.h:242
@ SPELL_ATTR7_DONT_CAUSE_SPELL_PUSHBACK
Definition: SharedDefines.h:619
@ SPELL_ATTR3_TREAT_AS_PERIODIC
Definition: SharedDefines.h:490
@ SPELL_ATTR3_SUPRESS_TARGET_PROCS
Definition: SharedDefines.h:482
@ DUEL_WON
Definition: SharedDefines.h:3585
@ SPELL_ATTR4_REACTIVE_DAMAGE_PROC
Definition: SharedDefines.h:516
@ SPELL_STATE_PREPARING
Definition: Spell.h:224
@ SPELL_STATE_CASTING
Definition: Spell.h:225
@ SPELL_AURA_DAMAGE_SHIELD
Definition: SpellAuraDefines.h:78
@ SPELL_AURA_SHARE_DAMAGE_PCT
Definition: SpellAuraDefines.h:363
@ CHANNEL_FLAG_DELAY
Definition: SpellDefines.h:39
@ AURA_INTERRUPT_FLAG_TAKE_DAMAGE
Definition: SpellDefines.h:45
@ AURA_INTERRUPT_FLAG_DIRECT_DAMAGE
Definition: SpellDefines.h:68
@ SPELL_INTERRUPT_FLAG_ABORT_ON_DMG
Definition: SpellDefines.h:31
@ SPELL_INTERRUPT_FLAG_PUSH_BACK
Definition: SpellDefines.h:28
@ CURRENT_CHANNELED_SPELL
Definition: Unit.h:980
@ CURRENT_GENERIC_SPELL
Definition: Unit.h:979
@ NODAMAGE
Definition: Unit.h:439
virtual void OwnerAttackedBy(Unit *)
Definition: CreatureAI.h:165
virtual void AttackedBy(Unit *)
Definition: CreatureAI.h:142
void SetLootRecipient(Unit *unit, bool withGroup=true)
Definition: Creature.cpp:1276
void SetLastDamagedTime(time_t val)
Definition: Creature.cpp:3550
void LowerPlayerDamageReq(uint32 unDamage, bool damagedByPlayer=true)
Definition: Creature.cpp:3656
CreatureAI * AI() const
Definition: Creature.h:134
bool IsPlayer() const
Definition: ObjectGuid.h:170
void UpdateAchievementCriteria(AchievementCriteriaTypes type, uint32 miscValue1=0, uint32 miscValue2=0, Unit *unit=nullptr)
Definition: PlayerUpdates.cpp:2123
void DurabilityPointLossForEquipSlot(EquipmentSlots slot)
Definition: Player.cpp:4703
Pet * GetPet() const
Definition: Player.cpp:8764
bool GetCommandStatus(uint32 command) const
Definition: Player.h:1154
uint32 ChannelInterruptFlags
Definition: SpellInfo.h:352
uint32 InterruptFlags
Definition: SpellInfo.h:350
virtual void DamageTaken(Unit *, uint32 &, DamageEffectType, SpellSchoolMask)
Definition: UnitAI.h:310
virtual void DamageDealt(Unit *, uint32 &, DamageEffectType)
Definition: UnitAI.h:305
int32 ModifyHealth(int32 val)
Definition: Unit.cpp:13981
Pet * ToPet()
Definition: Unit.h:2393
bool IsCreatedByPlayer() const
Definition: Unit.h:1826
Unit * GetCharmer() const
Definition: Unit.cpp:10556
static void Kill(Unit *killer, Unit *victim, bool durabilityLoss=true, WeaponAttackType attackType=BASE_ATTACK, SpellInfo const *spellProto=nullptr, Spell const *spell=nullptr)
Definition: Unit.cpp:17752
void RewardRage(uint32 damage, uint32 weaponSpeedHitFactor, bool attacker)
Definition: Unit.cpp:20142
void SetHealth(uint32 val)
Definition: Unit.cpp:15335
UnitAI * GetAI()
Definition: Unit.h:1316
ObjectGuid GetCharmerGUID() const
Definition: Unit.h:1817
Powers getPowerType() const
Definition: Unit.h:1457
void CombatStopWithPets(bool includingCast=false)
Definition: Unit.cpp:10405

◆ DealDamageMods()

void Unit::DealDamageMods ( Unit const *  victim,
uint32 damage,
uint32 absorb 
)
static
805{
806 if (!victim || !victim->IsAlive() || victim->IsInFlight() || (victim->GetTypeId() == TYPEID_UNIT && victim->ToCreature()->IsEvadingAttacks()))
807 {
808 if (absorb)
809 *absorb += damage;
810 damage = 0;
811 }
812}

◆ DealHeal()

int32 Unit::DealHeal ( Unit healer,
Unit victim,
uint32  addhealth 
)
static
10900{
10901 int32 gain = 0;
10902
10903 if (healer)
10904 {
10905 if (victim->IsAIEnabled)
10906 victim->GetAI()->HealReceived(healer, addhealth);
10907
10908 if (healer->IsAIEnabled)
10909 healer->GetAI()->HealDone(victim, addhealth);
10910 }
10911
10912 if (addhealth)
10913 gain = victim->ModifyHealth(int32(addhealth));
10914
10915 // Hook for OnHeal Event
10916 sScriptMgr->OnHeal(healer, victim, (uint32&)gain);
10917
10918 Unit* unit = healer;
10919
10920 if (healer && healer->GetTypeId() == TYPEID_UNIT && healer->ToCreature()->IsTotem())
10921 unit = healer->GetOwner();
10922
10923 if (!unit)
10924 return gain;
10925
10926 if (Player* player = unit->ToPlayer())
10927 {
10928 if (Battleground* bg = player->GetBattleground())
10929 bg->UpdatePlayerScore(player, SCORE_HEALING_DONE, gain);
10930
10931 // use the actual gain, as the overheal shall not be counted, skip gain 0 (it ignored anyway in to criteria)
10932 if (gain && player->InBattleground()) // pussywizard: InBattleground() optimization
10933 player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_HEALING_DONE, gain, 0, victim);
10934
10935 //player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_HEAL_CASTED, addhealth); // pussywizard: optimization
10936 }
10937
10938 /*if (Player* player = victim->ToPlayer())
10939 {
10940 //player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_TOTAL_HEALING_RECEIVED, gain); // pussywizard: optimization
10941 //player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_HEALING_RECEIVED, addhealth); // pussywizard: optimization
10942 }*/
10943
10944 return gain;
10945}
@ SCORE_HEALING_DONE
Definition: BattlegroundScore.h:34
@ ACHIEVEMENT_CRITERIA_TYPE_HEALING_DONE
Definition: DBCEnums.h:175
virtual void HealReceived(Unit *, uint32 &)
Definition: UnitAI.h:313
virtual void HealDone(Unit *, uint32 &)
Definition: UnitAI.h:316

◆ DealMeleeDamage()

void Unit::DealMeleeDamage ( CalcDamageInfo damageInfo,
bool  durabilityLoss 
)
1810{
1811 Unit* victim = damageInfo->target;
1812
1813 auto canTakeMeleeDamage = [&]()
1814 {
1815 return victim->IsAlive() && !victim->HasUnitState(UNIT_STATE_IN_FLIGHT) && (victim->GetTypeId() != TYPEID_UNIT || !victim->ToCreature()->IsEvadingAttacks());
1816 };
1817
1818 if (!canTakeMeleeDamage())
1819 {
1820 return;
1821 }
1822
1823 // Hmmmm dont like this emotes client must by self do all animations
1824 if (damageInfo->HitInfo & HITINFO_CRITICALHIT)
1826 if (damageInfo->blocked_amount && damageInfo->TargetState != VICTIMSTATE_BLOCKS)
1828
1829 if (damageInfo->TargetState == VICTIMSTATE_PARRY)
1830 {
1831 // Get attack timers
1832 float offtime = float(victim->getAttackTimer(OFF_ATTACK));
1833 float basetime = float(victim->getAttackTimer(BASE_ATTACK));
1834 // Reduce attack time
1835 if (victim->haveOffhandWeapon() && offtime < basetime)
1836 {
1837 float percent20 = victim->GetAttackTime(OFF_ATTACK) * 0.20f;
1838 float percent60 = 3.0f * percent20;
1839 if (offtime > percent20 && offtime <= percent60)
1840 victim->setAttackTimer(OFF_ATTACK, uint32(percent20));
1841 else if (offtime > percent60)
1842 {
1843 offtime -= 2.0f * percent20;
1844 victim->setAttackTimer(OFF_ATTACK, uint32(offtime));
1845 }
1846 }
1847 else
1848 {
1849 float percent20 = victim->GetAttackTime(BASE_ATTACK) * 0.20f;
1850 float percent60 = 3.0f * percent20;
1851 if (basetime > percent20 && basetime <= percent60)
1852 victim->setAttackTimer(BASE_ATTACK, uint32(percent20));
1853 else if (basetime > percent60)
1854 {
1855 basetime -= 2.0f * percent20;
1856 victim->setAttackTimer(BASE_ATTACK, uint32(basetime));
1857 }
1858 }
1859 }
1860
1861 for (uint8 i = 0; i < MAX_ITEM_PROTO_DAMAGES; ++i)
1862 {
1863 if (!canTakeMeleeDamage() || (!damageInfo->damages[i].damage && !damageInfo->damages[i].absorb && !damageInfo->damages[i].resist))
1864 {
1865 continue;
1866 }
1867
1868 // Call default DealDamage
1869 CleanDamage cleanDamage(damageInfo->cleanDamage, damageInfo->damages[i].absorb, damageInfo->attackType, damageInfo->hitOutCome);
1870 Unit::DealDamage(this, victim, damageInfo->damages[i].damage, &cleanDamage, DIRECT_DAMAGE, SpellSchoolMask(damageInfo->damages[i].damageSchoolMask), nullptr, durabilityLoss);
1871 }
1872
1873 // If this is a creature and it attacks from behind it has a probability to daze it's victim
1874 if ((damageInfo->damages[0].damage + damageInfo->damages[1].damage) && ((damageInfo->hitOutCome == MELEE_HIT_CRIT || damageInfo->hitOutCome == MELEE_HIT_CRUSHING || damageInfo->hitOutCome == MELEE_HIT_NORMAL || damageInfo->hitOutCome == MELEE_HIT_GLANCING) &&
1875 GetTypeId() != TYPEID_PLAYER && !ToCreature()->IsControlledByPlayer() && !victim->HasInArc(M_PI, this)
1876 && (victim->GetTypeId() == TYPEID_PLAYER || !victim->ToCreature()->isWorldBoss()) && !victim->IsVehicle()))
1877 {
1878 // -probability is between 0% and 40%
1879 // 20% base chance
1880 float Probability = 20.0f;
1881
1882 // there is a newbie protection, at level 10 just 7% base chance; assuming linear function
1883 if (victim->getLevel() < 30)
1884 Probability = 0.65f * victim->getLevel() + 0.5f;
1885
1886 uint32 VictimDefense = victim->GetDefenseSkillValue();
1887 uint32 AttackerMeleeSkill = GetUnitMeleeSkill();
1888
1889 // xinef: fix daze mechanics
1890 Probability -= ((float)VictimDefense - AttackerMeleeSkill) * 0.1428f;
1891
1892 if (Probability > 40.0f)
1893 Probability = 40.0f;
1894
1895 if (roll_chance_f(std::max(0.0f, Probability)))
1896 CastSpell(victim, 1604, true);
1897 }
1898
1899 if (GetTypeId() == TYPEID_PLAYER)
1900 ToPlayer()->CastItemCombatSpell(victim, damageInfo->attackType, damageInfo->procVictim, damageInfo->procEx);
1901
1902 // Do effect if any damage done to target
1903 if (damageInfo->damages[0].damage + damageInfo->damages[1].damage)
1904 {
1905 // We're going to call functions which can modify content of the list during iteration over it's elements
1906 // Let's copy the list so we can prevent iterator invalidation
1908 for (AuraEffectList::const_iterator dmgShieldItr = vDamageShieldsCopy.begin(); dmgShieldItr != vDamageShieldsCopy.end(); ++dmgShieldItr)
1909 {
1910 SpellInfo const* i_spellProto = (*dmgShieldItr)->GetSpellInfo();
1911 // Damage shield can be resisted...
1912 if (SpellMissInfo missInfo = victim->SpellHitResult(this, i_spellProto, false))
1913 {
1914 victim->SendSpellMiss(this, i_spellProto->Id, missInfo);
1915 continue;
1916 }
1917
1918 // ...or immuned
1919 if (IsImmunedToDamageOrSchool(i_spellProto))
1920 {
1921 victim->SendSpellDamageImmune(this, i_spellProto->Id);
1922 continue;
1923 }
1924
1925 uint32 damage = uint32(std::max(0, (*dmgShieldItr)->GetAmount())); // xinef: done calculated at amount calculation
1926
1927 if (Unit* caster = (*dmgShieldItr)->GetCaster())
1928 {
1929 damage = caster->SpellDamageBonusDone(this, i_spellProto, damage, SPELL_DIRECT_DAMAGE, (*dmgShieldItr)->GetEffIndex());
1930 damage = this->SpellDamageBonusTaken(caster, i_spellProto, damage, SPELL_DIRECT_DAMAGE);
1931 }
1932
1933 uint32 absorb = 0;
1934
1935 DamageInfo dmgInfo(victim, this, damage, i_spellProto, i_spellProto->GetSchoolMask(), SPELL_DIRECT_DAMAGE);
1936 Unit::CalcAbsorbResist(dmgInfo);
1937 absorb = dmgInfo.GetAbsorb();
1938 damage = dmgInfo.GetDamage();
1939
1940 Unit::DealDamageMods(this, damage, &absorb);
1941
1942 // TODO: Move this to a packet handler
1943 WorldPacket data(SMSG_SPELLDAMAGESHIELD, (8 + 8 + 4 + 4 + 4 + 4));
1944 data << victim->GetGUID();
1945 data << GetGUID();
1946 data << uint32(i_spellProto->Id);
1947 data << uint32(damage); // Damage
1948 int32 overkill = int32(damage) - int32(GetHealth());
1949 data << uint32(overkill > 0 ? overkill : 0); // Overkill
1950 data << uint32(i_spellProto->GetSchoolMask());
1951 victim->SendMessageToSet(&data, true);
1952
1953 Unit::DealDamage(victim, this, damage, 0, SPELL_DIRECT_DAMAGE, i_spellProto->GetSchoolMask(), i_spellProto, true);
1954 }
1955 }
1956}
@ EMOTE_ONESHOT_WOUND_CRITICAL
Definition: SharedDefines.h:1896
@ EMOTE_ONESHOT_PARRY_SHIELD
Definition: SharedDefines.h:1902
SpellMissInfo
Definition: SharedDefines.h:1490
bool isWorldBoss() const
Definition: Creature.h:114
void CastItemCombatSpell(Unit *target, WeaponAttackType attType, uint32 procVictim, uint32 procEx)
Definition: Player.cpp:7073
SpellSchoolMask GetSchoolMask() const
Definition: SpellInfo.cpp:1969
uint32 GetUnitMeleeSkill(Unit const *target=nullptr) const
Definition: Unit.h:1633
void SendSpellMiss(Unit *target, uint32 spellID, SpellMissInfo missInfo)
Definition: Unit.cpp:6345
uint32 GetDefenseSkillValue(Unit const *target=nullptr) const
Definition: Unit.cpp:3566
void SendSpellDamageImmune(Unit *target, uint32 spellId)
Definition: Unit.cpp:6369
SpellMissInfo SpellHitResult(Unit *victim, SpellInfo const *spell, bool canReflect=false)
Definition: Unit.cpp:3412
uint32 SpellDamageBonusTaken(Unit *caster, SpellInfo const *spellProto, uint32 pdamage, DamageEffectType damagetype, uint32 stack=1)
Definition: Unit.cpp:11702
void HandleEmoteCommand(uint32 emoteId)
Definition: Unit.cpp:1958
@ SMSG_SPELLDAMAGESHIELD
Definition: Opcodes.h:621
bool HasInArc(float arcangle, const Position *pos, float targetRadius=0.0f) const
Definition: Position.cpp:140

◆ DealSpellDamage()

void Unit::DealSpellDamage ( SpellNonMeleeDamage damageInfo,
bool  durabilityLoss,
Spell const *  spell = nullptr 
)
1435{
1436 if (damageInfo == 0)
1437 return;
1438
1439 Unit* victim = damageInfo->target;
1440
1441 if (!victim)
1442 return;
1443
1444 if (!victim->IsAlive() || victim->IsInFlight() || (victim->GetTypeId() == TYPEID_UNIT && victim->ToCreature()->IsEvadingAttacks()))
1445 return;
1446
1447 SpellInfo const* spellProto = damageInfo->spellInfo;
1448 if (!spellProto)
1449 {
1450 LOG_DEBUG("entities.unit", "Unit::DealSpellDamage has wrong damageInfo");
1451 return;
1452 }
1453
1454 // Call default DealDamage
1455 CleanDamage cleanDamage(damageInfo->cleanDamage, damageInfo->absorb, BASE_ATTACK, MELEE_HIT_NORMAL);
1456 Unit::DealDamage(this, victim, damageInfo->damage, &cleanDamage, SPELL_DIRECT_DAMAGE, SpellSchoolMask(damageInfo->schoolMask), spellProto, durabilityLoss, false, spell);
1457}
bool IsInFlight() const
Definition: Unit.h:1673
SpellInfo const * spellInfo
Definition: Unit.h:916

◆ DelayOwnedAuras()

void Unit::DelayOwnedAuras ( uint32  spellId,
ObjectGuid  caster,
int32  delaytime 
)
5369{
5370 AuraMapBoundsNonConst range = m_ownedAuras.equal_range(spellId);
5371 for (; range.first != range.second; ++range.first)
5372 {
5373 Aura* aura = range.first->second;
5374 if (!caster || aura->GetCasterGUID() == caster)
5375 {
5376 if (aura->GetDuration() < delaytime)
5377 aura->SetDuration(0);
5378 else
5379 aura->SetDuration(aura->GetDuration() - delaytime);
5380
5381 // update for out of range group members (on 1 slot use)
5383 LOG_DEBUG("spells.aura", "Aura {} partially interrupted on unit {}, new duration: {} ms", aura->GetId(), GetGUID().ToString(), aura->GetDuration());
5384 }
5385 }
5386}
int32 GetDuration() const
Definition: SpellAuras.h:133
void SetNeedClientUpdateForTargets() const
Definition: SpellAuras.cpp:1272
void SetDuration(int32 duration, bool withMods=false)
Definition: SpellAuras.cpp:882
std::pair< AuraMap::iterator, AuraMap::iterator > AuraMapBoundsNonConst
Definition: Unit.h:1297

◆ DeleteCharmInfo()

void Unit::DeleteCharmInfo ( )
15658{
15659 if (!m_charmInfo)
15660 return;
15661
15663 delete m_charmInfo;
15664 m_charmInfo = nullptr;
15665}
void RestoreState()
Definition: Unit.cpp:15686

◆ DeMorph()

void Unit::DeMorph ( )
4278{
4280}
uint32 GetNativeDisplayId() const
Definition: Unit.h:2165
virtual void SetDisplayId(uint32 modelId)
Definition: Unit.cpp:16840

◆ DisableRotate()

void Unit::DisableRotate ( bool  apply)
18294{
18295 if (GetTypeId() != TYPEID_UNIT)
18296 return;
18297
18298 if (apply)
18302}
@ UNIT_STATE_POSSESSED
Definition: Unit.h:341
void SetUnitFlag(UnitFlags flags)
Definition: Unit.h:1479

◆ DisableSpline()

void Unit::DisableSpline ( )
655{
658}
MovementFlags
Definition: Unit.h:550
@ MOVEMENTFLAG_SPLINE_ENABLED
Definition: Unit.h:579
@ MOVEMENTFLAG_FORWARD
Definition: Unit.h:552
@ MOVEMENTFLAG_BACKWARD
Definition: Unit.h:553
void _Interrupt()
Definition: MoveSpline.h:89

◆ Dismount()

void Unit::Dismount ( )
13429{
13430 if (!IsMounted())
13431 return;
13432
13435
13436 if (Player* thisPlayer = ToPlayer())
13437 {
13438 WorldPacket data(SMSG_MOVE_SET_COLLISION_HGT, GetPackGUID().size() + 4 + 4);
13439 data << GetPackGUID();
13440 data << uint32(GameTime::GetGameTime().count()); // Packet counter
13441 data << thisPlayer->GetCollisionHeight();
13442 thisPlayer->GetSession()->SendPacket(&data);
13443 }
13444
13445 WorldPacket data(SMSG_DISMOUNT, 8);
13446 data << GetPackGUID();
13447 SendMessageToSet(&data, true);
13448
13449 // dismount as a vehicle
13451 {
13452 // Send other players that we are no longer a vehicle
13453 data.Initialize(SMSG_PLAYER_VEHICLE_DATA, 8 + 4);
13454 data << GetPackGUID();
13455 data << uint32(0);
13456 ToPlayer()->SendMessageToSet(&data, true);
13457 // Remove vehicle from player
13459 }
13460
13462
13463 // only resummon old pet if the player is already added to a map
13464 // this prevents adding a pet to a not created map which would otherwise cause a crash
13465 // (it could probably happen when logging in after a previous crash)
13466 if (Player* player = ToPlayer())
13467 {
13468 sScriptMgr->AnticheatSetUnderACKmount(player);
13469
13470 if (Pet* pPet = player->GetPet())
13471 {
13472 if (pPet->HasUnitFlag(UNIT_FLAG_STUNNED) && !pPet->HasUnitState(UNIT_STATE_STUNNED))
13473 pPet->RemoveUnitFlag(UNIT_FLAG_STUNNED);
13474 }
13475 else
13476 player->ResummonPetTemporaryUnSummonedIfAny();
13477
13478 // xinef: if we have charmed npc, remove stun also
13479 if (Unit* charm = player->GetCharm())
13480 if (charm->GetTypeId() == TYPEID_UNIT && !charm->HasUnitState(UNIT_STATE_STUNNED))
13481 charm->RemoveUnitFlag(UNIT_FLAG_STUNNED);
13482 }
13483}
@ AURA_INTERRUPT_FLAG_NOT_MOUNTED
Definition: SpellDefines.h:50
@ UNIT_FLAG_STUNNED
Definition: Unit.h:466
@ UNIT_FLAG_MOUNT
Definition: Unit.h:475
@ UNIT_FIELD_MOUNTDISPLAYID
Definition: UpdateFields.h:126
void SendMessageToSet(WorldPacket const *data, bool self) const override
Definition: Player.h:1975
void RemoveVehicleKit()
Definition: Unit.cpp:18759
@ SMSG_PLAYER_VEHICLE_DATA
Definition: Opcodes.h:1221
@ SMSG_MOVE_SET_COLLISION_HGT
Definition: Opcodes.h:1332
@ SMSG_DISMOUNT
Definition: Opcodes.h:970

◆ EnergizeBySpell()

void Unit::EnergizeBySpell ( Unit victim,
uint32  SpellID,
uint32  Damage,
Powers  powertype 
)
11216{
11217 victim->ModifyPower(powerType, damage, false);
11218
11219 if (powerType != POWER_HAPPINESS)
11220 {
11221 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellID);
11222 victim->getHostileRefMgr().threatAssist(this, float(damage) * 0.5f, spellInfo);
11223 }
11224
11225 SendEnergizeSpellLog(victim, spellID, damage, powerType);
11226}
@ POWER_HAPPINESS
Definition: SharedDefines.h:245
void threatAssist(Unit *victim, float baseThreat, SpellInfo const *threatSpell=nullptr)
Definition: HostileRefMgr.cpp:35
void SendEnergizeSpellLog(Unit *victim, uint32 SpellID, uint32 Damage, Powers powertype)
Definition: Unit.cpp:11204

◆ EnterVehicle()

void Unit::EnterVehicle ( Unit base,
int8  seatId = -1 
)
19652{
19654
19655 if (Player* player = ToPlayer())
19656 {
19657 sScriptMgr->AnticheatSetUnderACKmount(player);
19658 sScriptMgr->AnticheatSetSkipOnePacketForASH(player, true);
19659 }
19660}
@ TRIGGERED_IGNORE_CASTER_MOUNTED_OR_ON_VEHICLE
Will ignore caster aura states including combat requirements and death state.
Definition: SpellDefines.h:144
@ VEHICLE_SPELL_RIDE_HARDCODED
Definition: VehicleDefines.h:53

◆ EnterVehicleUnattackable()

void Unit::EnterVehicleUnattackable ( Unit base,
int8  seatId = -1 
)
19663{
19664 CastCustomSpell(67830, SPELLVALUE_BASE_POINT0, seatId + 1, base, true);
19665}

◆ ExecuteDelayedUnitAINotifyEvent()

void Unit::ExecuteDelayedUnitAINotifyEvent ( )
20603{
20605 if (!this->IsInWorld() || this->IsDuringRemoveFromWorld())
20606 return;
20607
20608 Acore::AIRelocationNotifier notifier(*this);
20609 float radius = 60.0f;
20610 Cell::VisitAllObjects(this, notifier, radius);
20611}
@ NOTIFY_AI_RELOCATION
Definition: Object.h:63
void RemoveFromNotify(uint16 f)
Definition: Object.h:553
Definition: GridNotifiers.h:89
static void VisitAllObjects(WorldObject const *obj, T &visitor, float radius, bool dont_load=true)
Definition: CellImpl.h:207

◆ ExecuteDelayedUnitRelocationEvent()

void Unit::ExecuteDelayedUnitRelocationEvent ( )
20496{
20498 if (!this->IsInWorld() || this->IsDuringRemoveFromWorld())
20499 return;
20500
20501 if (this->HasSharedVision())
20502 for (SharedVisionList::const_iterator itr = this->GetSharedVisionList().begin(); itr != this->GetSharedVisionList().end(); ++itr)
20503 if (Player* player = (*itr))
20504 {
20505 if (player->IsOnVehicle(this) || !player->IsInWorld() || player->IsDuringRemoveFromWorld()) // players on vehicles have their own event executed (due to passenger relocation)
20506 continue;
20507 WorldObject* viewPoint = player;
20508 if (player->m_seer && player->m_seer->IsInWorld())
20509 viewPoint = player->m_seer;
20510 if (!viewPoint->IsPositionValid() || !player->IsPositionValid())
20511 continue;
20512
20513 if (Unit* active = viewPoint->ToUnit())
20514 {
20515 //if (active->IsVehicle()) // always check original unit here, last notify position is not relocated
20516 // active = player;
20517
20518 float dx = active->m_last_notify_position.GetPositionX() - active->GetPositionX();
20519 float dy = active->m_last_notify_position.GetPositionY() - active->GetPositionY();
20520 float dz = active->m_last_notify_position.GetPositionZ() - active->GetPositionZ();
20521 float distsq = dx * dx + dy * dy + dz * dz;
20522 float mindistsq = DynamicVisibilityMgr::GetReqMoveDistSq(active->FindMap()->GetEntry()->map_type);
20523 if (distsq < mindistsq)
20524 continue;
20525
20526 // this will be relocated below sharedvision!
20527 //active->m_last_notify_position.Relocate(active->GetPositionX(), active->GetPositionY(), active->GetPositionZ());
20528 }
20529
20530 Acore::PlayerRelocationNotifier relocateNoLarge(*player, false); // visit only objects which are not large; default distance
20531 Cell::VisitAllObjects(viewPoint, relocateNoLarge, player->GetSightRange() + VISIBILITY_INC_FOR_GOBJECTS);
20532 relocateNoLarge.SendToSelf();
20533 Acore::PlayerRelocationNotifier relocateLarge(*player, true); // visit only large objects; maximum distance
20534 Cell::VisitAllObjects(viewPoint, relocateLarge, MAX_VISIBILITY_DISTANCE);
20535 relocateLarge.SendToSelf();
20536 }
20537
20538 if (Player* player = this->ToPlayer())
20539 {
20540 WorldObject* viewPoint = player;
20541 if (player->m_seer && player->m_seer->IsInWorld())
20542 viewPoint = player->m_seer;
20543
20544 if (viewPoint->GetMapId() != player->GetMapId() || !viewPoint->IsPositionValid() || !player->IsPositionValid())
20545 return;
20546
20547 if (Unit* active = viewPoint->ToUnit())
20548 {
20549 if (active->IsVehicle())
20550 active = player;
20551
20552 if (!player->GetFarSightDistance())
20553 {
20554 float dx = active->m_last_notify_position.GetPositionX() - active->GetPositionX();
20555 float dy = active->m_last_notify_position.GetPositionY() - active->GetPositionY();
20556 float dz = active->m_last_notify_position.GetPositionZ() - active->GetPositionZ();
20557 float distsq = dx * dx + dy * dy + dz * dz;
20558
20559 float mindistsq = DynamicVisibilityMgr::GetReqMoveDistSq(active->FindMap()->GetEntry()->map_type);
20560 if (distsq < mindistsq)
20561 return;
20562
20563 active->m_last_notify_position.Relocate(active->GetPositionX(), active->GetPositionY(), active->GetPositionZ());
20564 }
20565 }
20566
20567 Acore::PlayerRelocationNotifier relocateNoLarge(*player, false); // visit only objects which are not large; default distance
20568 Cell::VisitAllObjects(viewPoint, relocateNoLarge, player->GetSightRange() + VISIBILITY_INC_FOR_GOBJECTS);
20569 relocateNoLarge.SendToSelf();
20570
20571 if (!player->GetFarSightDistance())
20572 {
20573 Acore::PlayerRelocationNotifier relocateLarge(*player, true); // visit only large objects; maximum distance
20574 Cell::VisitAllObjects(viewPoint, relocateLarge, MAX_VISIBILITY_DISTANCE);
20575 relocateLarge.SendToSelf();
20576 }
20577
20579 }
20580 else if (Creature* unit = this->ToCreature())
20581 {
20582 if (!unit->IsPositionValid())
20583 return;
20584
20585 float dx = unit->m_last_notify_position.GetPositionX() - unit->GetPositionX();
20586 float dy = unit->m_last_notify_position.GetPositionY() - unit->GetPositionY();
20587 float dz = unit->m_last_notify_position.GetPositionZ() - unit->GetPositionZ();
20588 float distsq = dx * dx + dy * dy + dz * dz;
20589 float mindistsq = DynamicVisibilityMgr::GetReqMoveDistSq(unit->FindMap()->GetEntry()->map_type);
20590 if (distsq < mindistsq)
20591 return;
20592
20593 unit->m_last_notify_position.Relocate(unit->GetPositionX(), unit->GetPositionY(), unit->GetPositionZ());
20594
20595 Acore::CreatureRelocationNotifier relocate(*unit);
20596 Cell::VisitAllObjects(unit, relocate, unit->GetVisibilityRange() + VISIBILITY_COMPENSATION);
20597
20599 }
20600}
@ NOTIFY_VISIBILITY_CHANGED
Definition: Object.h:64
#define MAX_VISIBILITY_DISTANCE
Definition: ObjectDefines.h:31
#define VISIBILITY_INC_FOR_GOBJECTS
Definition: ObjectDefines.h:28
#define VISIBILITY_COMPENSATION
Definition: ObjectDefines.h:26
static float GetReqMoveDistSq(uint32 map_type)
Definition: DynamicVisibility.h:53
Unit * ToUnit()
Definition: Object.h:200
SharedVisionList const & GetSharedVisionList()
Definition: Unit.h:1886
bool HasSharedVision() const
Definition: Unit.h:1889
uint32 GetMapId() const
Definition: Position.h:276
void AddToNotify(uint16 f)
Definition: Object.cpp:2890
Definition: GridNotifiers.h:81
Definition: GridNotifiers.h:73
bool IsPositionValid() const
Definition: Position.cpp:175

◆ ExitVehicle()

void Unit::ExitVehicle ( Position const *  exitPosition = nullptr)

This function can be called at upper level code to initialize an exit from the passenger's side.

The following call would not even be executed successfully as the SPELL_AURA_CONTROL_VEHICLE unapply handler already calls _ExitVehicle without specifying an exitposition. The subsequent call below would return on if (!m_vehicle).

To do: We need to allow SPELL_AURA_CONTROL_VEHICLE unapply handlers in spellscripts to specify exit coordinates and either store those per passenger, or we need to init spline movement based on those coordinates in unapply handlers, and relocate exiting passengers based on Unit::moveSpline data. Either way, Coming Soon(TM)

19750{
19752 if (!m_vehicle)
19753 return;
19754
19756 if (Player* player = ToPlayer())
19757 {
19758 player->SetCanTeleport(true);
19759 }
19763 /*_ExitVehicle(exitPosition);*/
19770
19771 if (Player* player = ToPlayer())
19772 {
19773 sScriptMgr->AnticheatSetUnderACKmount(player);
19774 sScriptMgr->AnticheatSetSkipOnePacketForASH(player, true);
19775 }
19776}
Unit * GetVehicleBase() const
Definition: Unit.cpp:18774

◆ FindCurrentSpellBySpellId()

Spell * Unit::FindCurrentSpellBySpellId ( uint32  spell_id) const
4073{
4074 for (uint32 i = 0; i < CURRENT_MAX_SPELL; i++)
4075 if (m_currentSpells[i] && m_currentSpells[i]->m_spellInfo->Id == spell_id)
4076 return m_currentSpells[i];
4077 return nullptr;
4078}

◆ FinishSpell()

void Unit::FinishSpell ( CurrentSpellTypes  spellType,
bool  ok = true 
)
4016{
4017 Spell* spell = m_currentSpells[spellType];
4018 if (!spell)
4019 return;
4020
4021 if (spellType == CURRENT_CHANNELED_SPELL)
4022 spell->SendChannelUpdate(0);
4023
4024 spell->finish(ok);
4025}
void SendChannelUpdate(uint32 time)
Definition: Spell.cpp:5141

◆ GetAffectingPlayer()

Player * Unit::GetAffectingPlayer ( ) const
10574{
10575 if (!GetCharmerOrOwnerGUID())
10576 return const_cast<Unit*>(this)->ToPlayer();
10577
10578 if (Unit* owner = GetCharmerOrOwner())
10580
10581 return nullptr;
10582}
Unit * GetCharmerOrOwner() const
Definition: Unit.h:1844
ObjectGuid GetCharmerOrOwnerGUID() const
Definition: Unit.h:1827

◆ GetAI()

UnitAI * Unit::GetAI ( )
inline
1316{ return i_AI; }

◆ GetAllMinionsByEntry()

void Unit::GetAllMinionsByEntry ( std::list< Creature * > &  Minions,
uint32  entry 
)
10800{
10801 for (Unit::ControlSet::iterator itr = m_Controlled.begin(); itr != m_Controlled.end();)
10802 {
10803 Unit* unit = *itr;
10804 ++itr;
10805 if (unit->GetEntry() == entry && unit->GetTypeId() == TYPEID_UNIT
10806 && unit->ToCreature()->IsSummon()) // minion, actually
10807 Minions.push_back(unit->ToCreature());
10808 }
10809}
bool IsSummon() const
Definition: Unit.h:1410

◆ GetAPMultiplier()

float Unit::GetAPMultiplier ( WeaponAttackType  attType,
bool  normalized 
)
17280{
17281 if (!normalized || GetTypeId() != TYPEID_PLAYER)
17282 return float(GetAttackTime(attType)) / 1000.0f;
17283
17284 Item* Weapon = ToPlayer()->GetWeaponForAttack(attType, true);
17285 if (!Weapon)
17286 return 2.4f; // fist attack
17287
17288 switch (Weapon->GetTemplate()->InventoryType)
17289 {
17290 case INVTYPE_2HWEAPON:
17291 return 3.3f;
17292 case INVTYPE_RANGED:
17294 case INVTYPE_THROWN:
17295 return 2.8f;
17296 case INVTYPE_WEAPON:
17299 default:
17300 return Weapon->GetTemplate()->SubClass == ITEM_SUBCLASS_WEAPON_DAGGER ? 1.7f : 2.4f;
17301 }
17302}
@ ITEM_SUBCLASS_WEAPON_DAGGER
Definition: ItemTemplate.h:368
@ INVTYPE_RANGED
Definition: ItemTemplate.h:280
@ INVTYPE_THROWN
Definition: ItemTemplate.h:290
@ INVTYPE_RANGEDRIGHT
Definition: ItemTemplate.h:291
@ INVTYPE_WEAPON
Definition: ItemTemplate.h:278
@ INVTYPE_WEAPONMAINHAND
Definition: ItemTemplate.h:286
@ INVTYPE_WEAPONOFFHAND
Definition: ItemTemplate.h:287
@ INVTYPE_2HWEAPON
Definition: ItemTemplate.h:282
Weapon
Definition: boss_arlokk.cpp:75
Definition: Item.h:214
Item * GetWeaponForAttack(WeaponAttackType attackType, bool useable=false) const
Definition: PlayerStorage.cpp:519

◆ GetAppliedAuras() [1/2]

AuraApplicationMap & Unit::GetAppliedAuras ( )
inline
1921{ return m_appliedAuras; }

◆ GetAppliedAuras() [2/2]

AuraApplicationMap const & Unit::GetAppliedAuras ( ) const
inline
1922{ return m_appliedAuras; }

◆ GetArmor()

uint32 Unit::GetArmor ( ) const
inline
@ SPELL_SCHOOL_NORMAL
Definition: SharedDefines.h:255
uint32 GetResistance(SpellSchools school) const
Definition: Unit.h:1433

◆ getAttackerForHelper()

Unit * Unit::getAttackerForHelper ( ) const
inline
1367 {
1368 if (GetVictim() != nullptr)
1369 return GetVictim();
1370
1371 if (!IsEngaged())
1372 return nullptr;
1373
1374 if (!m_attackers.empty())
1375 return *(m_attackers.begin());
1376
1377 return nullptr;
1378 }
bool IsEngaged() const
Definition: Unit.h:1682
Unit * GetVictim() const
Definition: Unit.h:1386

◆ getAttackers()

AttackerSet const & Unit::getAttackers ( ) const
inline
1383{ return m_attackers; }

◆ GetAttackTime()

uint32 Unit::GetAttackTime ( WeaponAttackType  att) const
inline
1468 {
1469 float f_BaseAttackTime = GetFloatValue(static_cast<uint16>(UNIT_FIELD_BASEATTACKTIME) + att) / m_modAttackSpeedPct[att];
1470 return (uint32)f_BaseAttackTime;
1471 }

◆ getAttackTimer()

int32 Unit::getAttackTimer ( WeaponAttackType  type) const
inline
1342{ return m_attackTimer[type]; }

◆ GetAura()

Aura * Unit::GetAura ( uint32  spellId,
ObjectGuid  casterGUID = ObjectGuid::Empty,
ObjectGuid  itemCasterGUID = ObjectGuid::Empty,
uint8  reqEffMask = 0 
) const
5488{
5489 AuraApplication* aurApp = GetAuraApplication(spellId, casterGUID, itemCasterGUID, reqEffMask);
5490 return aurApp ? aurApp->GetBase() : nullptr;
5491}
AuraApplication * GetAuraApplication(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, ObjectGuid itemCasterGUID=ObjectGuid::Empty, uint8 reqEffMask=0, AuraApplication *except=nullptr) const
Definition: Unit.cpp:5468

◆ GetAuraApplication()

AuraApplication * Unit::GetAuraApplication ( uint32  spellId,
ObjectGuid  casterGUID = ObjectGuid::Empty,
ObjectGuid  itemCasterGUID = ObjectGuid::Empty,
uint8  reqEffMask = 0,
AuraApplication except = nullptr 
) const
5469{
5470 AuraApplicationMapBounds range = m_appliedAuras.equal_range(spellId);
5471 for (; range.first != range.second; ++range.first)
5472 {
5473 AuraApplication* app = range.first->second;
5474 Aura const* aura = app->GetBase();
5475
5476 if (((aura->GetEffectMask() & reqEffMask) == reqEffMask)
5477 && (!casterGUID || aura->GetCasterGUID() == casterGUID)
5478 && (!itemCasterGUID || aura->GetCastItemGUID() == itemCasterGUID)
5479 && (!except || except != app))
5480 {
5481 return app;
5482 }
5483 }
5484 return nullptr;
5485}
uint8 GetEffectMask() const
Definition: SpellAuras.h:176
ObjectGuid GetCastItemGUID() const
Definition: SpellAuras.h:103
std::pair< AuraApplicationMap::const_iterator, AuraApplicationMap::const_iterator > AuraApplicationMapBounds
Definition: Unit.h:1300

◆ GetAuraApplicationOfRankedSpell()

AuraApplication * Unit::GetAuraApplicationOfRankedSpell ( uint32  spellId,
ObjectGuid  casterGUID = ObjectGuid::Empty,
ObjectGuid  itemCasterGUID = ObjectGuid::Empty,
uint8  reqEffMask = 0,
AuraApplication except = nullptr 
) const
5494{
5495 uint32 rankSpell = sSpellMgr->GetFirstSpellInChain(spellId);
5496 while (rankSpell)
5497 {
5498 if (AuraApplication* aurApp = GetAuraApplication(rankSpell, casterGUID, itemCasterGUID, reqEffMask, except))
5499 return aurApp;
5500 rankSpell = sSpellMgr->GetNextSpellInChain(rankSpell);
5501 }
5502 return nullptr;
5503}

◆ GetAuraCount()

uint32 Unit::GetAuraCount ( uint32  spellId) const
5583{
5584 uint32 count = 0;
5585 AuraApplicationMapBounds range = m_appliedAuras.equal_range(spellId);
5586
5587 for (AuraApplicationMap::const_iterator itr = range.first; itr != range.second; ++itr)
5588 {
5589 if (itr->second->GetBase()->GetStackAmount() == 0)
5590 ++count;
5591 else
5592 count += (uint32)itr->second->GetBase()->GetStackAmount();
5593 }
5594
5595 return count;
5596}

◆ GetAuraEffect() [1/3]

AuraEffect * Unit::GetAuraEffect ( AuraType  type,
SpellFamilyNames  family,
uint32  familyFlag1,
uint32  familyFlag2,
uint32  familyFlag3,
ObjectGuid  casterGUID = ObjectGuid::Empty 
) const
5441{
5442 AuraEffectList const& auras = GetAuraEffectsByType(type);
5443 for (AuraEffectList::const_iterator i = auras.begin(); i != auras.end(); ++i)
5444 {
5445 SpellInfo const* spell = (*i)->GetSpellInfo();
5446 if (spell->SpellFamilyName == uint32(family) && spell->SpellFamilyFlags.HasFlag(familyFlag1, familyFlag2, familyFlag3))
5447 {
5448 if (casterGUID && (*i)->GetCasterGUID() != casterGUID)
5449 continue;
5450 return (*i);
5451 }
5452 }
5453 return nullptr;
5454}
flag96 SpellFamilyFlags
Definition: SpellInfo.h:386
uint32 SpellFamilyName
Definition: SpellInfo.h:385
bool HasFlag(uint32 p1=0, uint32 p2=0, uint32 p3=0) const
Definition: Util.h:463

◆ GetAuraEffect() [2/3]

AuraEffect * Unit::GetAuraEffect ( AuraType  type,
SpellFamilyNames  name,
uint32  iconId,
uint8  effIndex 
) const
5427{
5428 AuraEffectList const& auras = GetAuraEffectsByType(type);
5429 for (Unit::AuraEffectList::const_iterator itr = auras.begin(); itr != auras.end(); ++itr)
5430 {
5431 if (effIndex != (*itr)->GetEffIndex())
5432 continue;
5433 SpellInfo const* spell = (*itr)->GetSpellInfo();
5434 if (spell->SpellIconID == iconId && spell->SpellFamilyName == name)
5435 return *itr;
5436 }
5437 return nullptr;
5438}
uint32 SpellIconID
Definition: SpellInfo.h:378

◆ GetAuraEffect() [3/3]

AuraEffect * Unit::GetAuraEffect ( uint32  spellId,
uint8  effIndex,
ObjectGuid  casterGUID = ObjectGuid::Empty 
) const
5401{
5402 AuraApplicationMapBounds range = m_appliedAuras.equal_range(spellId);
5403 for (AuraApplicationMap::const_iterator itr = range.first; itr != range.second; ++itr)
5404 {
5405 if (itr->second->HasEffect(effIndex)
5406 && (!caster || itr->second->GetBase()->GetCasterGUID() == caster))
5407 {
5408 return itr->second->GetBase()->GetEffect(effIndex);
5409 }
5410 }
5411 return nullptr;
5412}

◆ GetAuraEffectDummy()

AuraEffect * Unit::GetAuraEffectDummy ( uint32  spellid) const
5457{
5459 for (Unit::AuraEffectList::const_iterator itr = auras.begin(); itr != auras.end(); ++itr)
5460 {
5461 if ((*itr)->GetId() == spellid)
5462 return *itr;
5463 }
5464
5465 return nullptr;
5466}
@ SPELL_AURA_DUMMY
Definition: SpellAuraDefines.h:67

◆ GetAuraEffectOfRankedSpell()

AuraEffect * Unit::GetAuraEffectOfRankedSpell ( uint32  spellId,
uint8  effIndex,
ObjectGuid  casterGUID = ObjectGuid::Empty 
) const
5415{
5416 uint32 rankSpell = sSpellMgr->GetFirstSpellInChain(spellId);
5417 while (rankSpell)
5418 {
5419 if (AuraEffect* aurEff = GetAuraEffect(rankSpell, effIndex, caster))
5420 return aurEff;
5421 rankSpell = sSpellMgr->GetNextSpellInChain(rankSpell);
5422 }
5423 return nullptr;
5424}
AuraEffect * GetAuraEffect(uint32 spellId, uint8 effIndex, ObjectGuid casterGUID=ObjectGuid::Empty) const
Definition: Unit.cpp:5400

◆ GetAuraEffectsByType()

AuraEffectList const & Unit::GetAuraEffectsByType ( AuraType  type) const
inline
1964{ return m_modAuras[type]; }

◆ GetAuraOfRankedSpell()

Aura * Unit::GetAuraOfRankedSpell ( uint32  spellId,
ObjectGuid  casterGUID = ObjectGuid::Empty,
ObjectGuid  itemCasterGUID = ObjectGuid::Empty,
uint8  reqEffMask = 0 
) const
5506{
5507 AuraApplication* aurApp = GetAuraApplicationOfRankedSpell(spellId, casterGUID, itemCasterGUID, reqEffMask);
5508 return aurApp ? aurApp->GetBase() : nullptr;
5509}
AuraApplication * GetAuraApplicationOfRankedSpell(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, ObjectGuid itemCasterGUID=ObjectGuid::Empty, uint8 reqEffMask=0, AuraApplication *except=nullptr) const
Definition: Unit.cpp:5493

◆ GetCastingTimeForBonus()

uint32 Unit::GetCastingTimeForBonus ( SpellInfo const *  spellProto,
DamageEffectType  damagetype,
uint32  CastingTime 
) const
17140{
17141 // Not apply this to creature casted spells with casttime == 0
17142 if (CastingTime == 0 && GetTypeId() == TYPEID_UNIT && !IsPet())
17143 return 3500;
17144
17145 if (CastingTime > 7000) CastingTime = 7000;
17146 if (CastingTime < 1500) CastingTime = 1500;
17147
17148 if (damagetype == DOT && !spellProto->IsChanneled())
17149 CastingTime = 3500;
17150
17151 int32 overTime = 0;
17152 uint8 effects = 0;
17153 bool DirectDamage = false;
17154 bool AreaEffect = false;
17155
17156 for (uint32 i = 0; i < MAX_SPELL_EFFECTS; i++)
17157 {
17158 switch (spellProto->Effects[i].Effect)
17159 {
17165 case SPELL_EFFECT_HEAL:
17166 DirectDamage = true;
17167 break;
17169 switch (spellProto->Effects[i].ApplyAuraName)
17170 {
17174 if (spellProto->GetDuration())
17175 overTime = spellProto->GetDuration();
17176 break;
17177 default:
17178 // -5% per additional effect
17179 ++effects;
17180 break;
17181 }
17182 default:
17183 break;
17184 }
17185
17186 if (spellProto->Effects[i].IsTargetingArea())
17187 AreaEffect = true;
17188 }
17189
17190 // Combined Spells with Both Over Time and Direct Damage
17191 if (overTime > 0 && DirectDamage)
17192 {
17193 // mainly for DoTs which are 3500 here otherwise
17194 uint32 OriginalCastTime = spellProto->CalcCastTime();
17195 if (OriginalCastTime > 7000) OriginalCastTime = 7000;
17196 if (OriginalCastTime < 1500) OriginalCastTime = 1500;
17197 // Portion to Over Time
17198 float PtOT = (overTime / 15000.0f) / ((overTime / 15000.0f) + (OriginalCastTime / 3500.0f));
17199
17200 if (damagetype == DOT)
17201 CastingTime = uint32(CastingTime * PtOT);
17202 else if (PtOT < 1.0f)
17203 CastingTime = uint32(CastingTime * (1 - PtOT));
17204 else
17205 CastingTime = 0;
17206 }
17207
17208 // Area Effect Spells receive only half of bonus
17209 if (AreaEffect)
17210 CastingTime /= 2;
17211
17212 // 50% for damage and healing spells for leech spells from damage bonus and 0% from healing
17213 for (uint8 j = 0; j < MAX_SPELL_EFFECTS; ++j)
17214 {
17215 if (spellProto->Effects[j].Effect == SPELL_EFFECT_HEALTH_LEECH ||
17216 (spellProto->Effects[j].Effect == SPELL_EFFECT_APPLY_AURA && spellProto->Effects[j].ApplyAuraName == SPELL_AURA_PERIODIC_LEECH))
17217 {
17218 CastingTime /= 2;
17219 break;
17220 }
17221 }
17222
17223 // -5% of total per any additional effect
17224 for (uint8 i = 0; i < effects; ++i)
17225 CastingTime *= 0.95f;
17226
17227 return CastingTime;
17228}
@ SPELL_EFFECT_POWER_BURN
Definition: SharedDefines.h:812
@ SPELL_EFFECT_HEALTH_LEECH
Definition: SharedDefines.h:759
@ SPELL_EFFECT_HEAL
Definition: SharedDefines.h:760
@ SPELL_EFFECT_ENVIRONMENTAL_DAMAGE
Definition: SharedDefines.h:757
@ SPELL_EFFECT_POWER_DRAIN
Definition: SharedDefines.h:758
@ SPELL_EFFECT_SCHOOL_DAMAGE
Definition: SharedDefines.h:752
@ SPELL_EFFECT_APPLY_AURA
Definition: SharedDefines.h:756
@ SPELL_AURA_PERIODIC_DAMAGE
Definition: SpellAuraDefines.h:66
@ SPELL_AURA_PERIODIC_HEAL
Definition: SpellAuraDefines.h:71
@ SPELL_AURA_PERIODIC_LEECH
Definition: SpellAuraDefines.h:116

◆ GetCharm()

Unit * Unit::GetCharm ( ) const
10615{
10616 if (ObjectGuid charm_guid = GetCharmGUID())
10617 {
10618 if (Unit* pet = ObjectAccessor::GetUnit(*this, charm_guid))
10619 return pet;
10620
10621 LOG_ERROR("entities.unit", "Unit::GetCharm: Charmed creature {} not exist.", charm_guid.ToString());
10623 }
10624
10625 return nullptr;
10626}
@ UNIT_FIELD_CHARM
Definition: UpdateFields.h:86
void SetGuidValue(uint16 index, ObjectGuid value)
Definition: Object.cpp:723
ObjectGuid GetCharmGUID() const
Definition: Unit.h:1819
Unit * GetUnit(WorldObject const &, ObjectGuid const guid)
Definition: ObjectAccessor.cpp:204

◆ GetCharmer()

Unit * Unit::GetCharmer ( ) const
10557{
10558 if (ObjectGuid charmerGUID = GetCharmerGUID())
10559 return ObjectAccessor::GetUnit(*this, charmerGUID);
10560
10561 return nullptr;
10562}

◆ GetCharmerGUID()

ObjectGuid Unit::GetCharmerGUID ( ) const
inline
@ UNIT_FIELD_CHARMEDBY
Definition: UpdateFields.h:89
ObjectGuid GetGuidValue(uint16 index) const
Definition: Object.cpp:337

◆ GetCharmerOrOwner()

Unit * Unit::GetCharmerOrOwner ( ) const
inline
1844{ return GetCharmerGUID() ? GetCharmer() : GetOwner(); }

◆ GetCharmerOrOwnerGUID()

ObjectGuid Unit::GetCharmerOrOwnerGUID ( ) const
inline
1827{ return GetCharmerGUID() ? GetCharmerGUID() : GetOwnerGUID(); }

◆ GetCharmerOrOwnerOrOwnGUID()

ObjectGuid Unit::GetCharmerOrOwnerOrOwnGUID ( ) const
inline
1829 {
1830 if (ObjectGuid guid = GetCharmerOrOwnerGUID())
1831 return guid;
1832
1833 return GetGUID();
1834 }

◆ GetCharmerOrOwnerOrSelf()

Unit * Unit::GetCharmerOrOwnerOrSelf ( ) const
inline
1846 {
1847 if (Unit* u = GetCharmerOrOwner())
1848 return u;
1849
1850 return (Unit*)this;
1851 }

◆ GetCharmerOrOwnerPlayerOrPlayerItself()

Player * Unit::GetCharmerOrOwnerPlayerOrPlayerItself ( ) const
10565{
10567 if (guid.IsPlayer())
10568 return ObjectAccessor::GetPlayer(*this, guid);
10569
10570 return const_cast<Unit*>(this)->ToPlayer();
10571}
Player * GetPlayer(Map const *, ObjectGuid const guid)
Definition: ObjectAccessor.cpp:225

◆ GetCharmGUID()

ObjectGuid Unit::GetCharmGUID ( ) const
inline
1819{ return GetGuidValue(UNIT_FIELD_CHARM); }

◆ GetCharmInfo()

CharmInfo * Unit::GetCharmInfo ( )
inline
1880{ return m_charmInfo; }

◆ getClass()

uint8 Unit::getClass ( ) const
inline
1424{ return GetByteValue(UNIT_FIELD_BYTES_0, 1); }
@ UNIT_FIELD_BYTES_0
Definition: UpdateFields.h:95
uint8 GetByteValue(uint16 index, uint8 offset) const
Definition: Object.cpp:323

◆ getClassMask()

uint32 Unit::getClassMask ( ) const
inline
1425{ return 1 << (getClass() - 1); }

◆ GetCollisionHeight()

float Unit::GetCollisionHeight ( ) const
overridevirtual

Return collision height sent to client.

Reimplemented from WorldObject.

21111{
21112 float scaleMod = GetObjectScale(); // 99% sure about this
21113 float defaultHeight = DEFAULT_COLLISION_HEIGHT * scaleMod;
21114
21115 CreatureDisplayInfoEntry const* displayInfo = sCreatureDisplayInfoStore.AssertEntry(GetNativeDisplayId());
21116 CreatureModelDataEntry const* modelData = sCreatureModelDataStore.AssertEntry(displayInfo->ModelId);
21117 float collisionHeight = 0.0f;
21118
21119 if (IsMounted())
21120 {
21122 {
21123 if (CreatureModelDataEntry const* mountModelData = sCreatureModelDataStore.LookupEntry(mountDisplayInfo->ModelId))
21124 {
21125 collisionHeight = scaleMod * (mountModelData->MountHeight + modelData->CollisionHeight * modelData->Scale * displayInfo->scale * 0.5f);
21126 }
21127 }
21128 }
21129 else
21130 collisionHeight = scaleMod * modelData->CollisionHeight * modelData->Scale * displayInfo->scale;
21131
21132 return collisionHeight == 0.0f ? defaultHeight : collisionHeight;
21133}
DBCStorage< CreatureDisplayInfoEntry > sCreatureDisplayInfoStore(CreatureDisplayInfofmt)
DBCStorage< CreatureModelDataEntry > sCreatureModelDataStore(CreatureModelDatafmt)
#define DEFAULT_COLLISION_HEIGHT
Definition: ObjectDefines.h:50
float GetObjectScale() const
Definition: Object.h:112
Definition: DBCStructure.h:721
uint32 ModelId
Definition: DBCStructure.h:723
float scale
Definition: DBCStructure.h:726
Definition: DBCStructure.h:775
float Scale
Definition: DBCStructure.h:780
float CollisionHeight
Definition: DBCStructure.h:791

◆ GetCollisionRadius()

float Unit::GetCollisionRadius ( ) const
overridevirtual

this method gets the radius of a Unit by DB if any value is defined, otherwise it gets the value by the DBC

If the player is mounted the radius also takes in consideration the mount size

Returns
float The radius of a unit

Reimplemented from WorldObject.

21105{
21106 return GetCollisionWidth() / 2;
21107}
float GetCollisionWidth() const override
this method gets the diameter of a Unit by DB if any value is defined, otherwise it gets the value by...
Definition: Unit.cpp:21067

◆ GetCollisionWidth()

float Unit::GetCollisionWidth ( ) const
overridevirtual

this method gets the diameter of a Unit by DB if any value is defined, otherwise it gets the value by the DBC

If the player is mounted the diameter also takes in consideration the mount size

Returns
float The diameter of a unit

Dismounting case - use basic default model data

Reimplemented from WorldObject.

21068{
21069 if (GetTypeId() == TYPEID_PLAYER)
21070 return GetObjectSize();
21071
21072 float scaleMod = GetObjectScale(); // 99% sure about this
21073 float objectSize = GetObjectSize();
21074 float defaultSize = DEFAULT_WORLD_OBJECT_SIZE * scaleMod;
21075
21077 CreatureDisplayInfoEntry const* displayInfo = sCreatureDisplayInfoStore.AssertEntry(GetNativeDisplayId());
21078 CreatureModelDataEntry const* modelData = sCreatureModelDataStore.AssertEntry(displayInfo->ModelId);
21079
21080 if (IsMounted())
21081 {
21083 {
21084 if (CreatureModelDataEntry const* mountModelData = sCreatureModelDataStore.LookupEntry(mountDisplayInfo->ModelId))
21085 {
21086 if (G3D::fuzzyGt(mountModelData->CollisionWidth, modelData->CollisionWidth))
21087 modelData = mountModelData;
21088 }
21089 }
21090 }
21091
21092 float collisionWidth = scaleMod * modelData->CollisionWidth * modelData->Scale * displayInfo->scale * 2;
21093 // if the objectSize is the default value or the creature is mounted and we have a DBC value, then we can retrieve DBC value instead
21094 return G3D::fuzzyGt(collisionWidth, 0.0f) && (G3D::fuzzyEq(objectSize,defaultSize) || IsMounted()) ? collisionWidth : objectSize;
21095}
#define DEFAULT_WORLD_OBJECT_SIZE
Definition: ObjectDefines.h:45
float GetObjectSize() const
Definition: Object.cpp:2717
float CollisionWidth
Definition: DBCStructure.h:790

◆ GetCombatRatingDamageReduction()

uint32 Unit::GetCombatRatingDamageReduction ( CombatRating  cr,
float  rate,
float  cap,
uint32  damage 
) const
private
19228{
19229 float percent = std::min(GetCombatRatingReduction(cr) * rate, cap);
19230 return CalculatePct(damage, percent);
19231}
float GetCombatRatingReduction(CombatRating cr) const
Definition: Unit.cpp:19215

◆ GetCombatRatingReduction()

float Unit::GetCombatRatingReduction ( CombatRating  cr) const
private
19216{
19217 if (Player const* player = ToPlayer())
19218 return player->GetRatingBonusValue(cr);
19219 // Player's pet get resilience from owner
19220 else if (IsPet() && GetOwner())
19221 if (Player* owner = GetOwner()->ToPlayer())
19222 return owner->GetRatingBonusValue(cr);
19223
19224 return 0.0f;
19225}

◆ GetCombatReach()

float Unit::GetCombatReach ( ) const
inlineoverridevirtual

Reimplemented from WorldObject.

@ UNIT_FIELD_COMBATREACH
Definition: UpdateFields.h:123

◆ GetCombatTimer()

uint32 Unit::GetCombatTimer ( ) const
inline
1695{ return m_CombatTimer; }

◆ GetComboPoints() [1/2]

uint8 Unit::GetComboPoints ( ObjectGuid const &  guid) const
inline
2286{ return (m_comboTarget && m_comboTarget->GetGUID() == guid) ? m_comboPoints : 0; }

◆ GetComboPoints() [2/2]

uint8 Unit::GetComboPoints ( Unit const *  who = nullptr) const
inline

--------—Combo point system----------------—

2285{ return (who && m_comboTarget != who) ? 0 : m_comboPoints; }

◆ GetComboTarget()

Unit * Unit::GetComboTarget ( ) const
inline
2287{ return m_comboTarget; }

◆ GetComboTargetGUID()

ObjectGuid const Unit::GetComboTargetGUID ( ) const
inline

◆ GetCreateHealth()

uint32 Unit::GetCreateHealth ( ) const
inline
@ UNIT_FIELD_BASE_HEALTH
Definition: UpdateFields.h:160

◆ GetCreateMana()

uint32 Unit::GetCreateMana ( ) const
inline
@ UNIT_FIELD_BASE_MANA
Definition: UpdateFields.h:159

◆ GetCreatePowers()

uint32 Unit::GetCreatePowers ( Powers  power) const
15498{
15499 // Only hunter pets have POWER_FOCUS and POWER_HAPPINESS
15500 switch (power)
15501 {
15502 case POWER_MANA:
15503 return GetCreateMana();
15504 case POWER_RAGE:
15505 return 1000;
15506 case POWER_FOCUS:
15507 return (GetTypeId() == TYPEID_PLAYER || !((Creature const*)this)->IsPet() || ((Pet const*)this)->getPetType() != HUNTER_PET ? 0 : 100);
15508 case POWER_ENERGY:
15509 return 100;
15510 case POWER_HAPPINESS:
15511 return (GetTypeId() == TYPEID_PLAYER || !((Creature const*)this)->IsPet() || ((Pet const*)this)->getPetType() != HUNTER_PET ? 0 : 1050000);
15512 case POWER_RUNIC_POWER:
15513 return 1000;
15514 case POWER_RUNE:
15515 return 0;
15516 case POWER_HEALTH:
15517 return 0;
15518 default:
15519 break;
15520 }
15521
15522 return 0;
15523}
@ POWER_HEALTH
Definition: SharedDefines.h:250
@ POWER_RUNIC_POWER
Definition: SharedDefines.h:247
@ POWER_ENERGY
Definition: SharedDefines.h:244
@ POWER_RUNE
Definition: SharedDefines.h:246
@ POWER_FOCUS
Definition: SharedDefines.h:243
uint32 GetCreateMana() const
Definition: Unit.h:2038

◆ GetCreateStat()

float Unit::GetCreateStat ( Stats  stat) const
inline
2042{ return m_createStats[stat]; }

◆ GetCreatorGUID()

ObjectGuid Unit::GetCreatorGUID ( ) const
inline
@ UNIT_FIELD_CREATEDBY
Definition: UpdateFields.h:91

◆ GetCreatureType()

uint32 Unit::GetCreatureType ( ) const
15040{
15041 if (GetTypeId() == TYPEID_PLAYER)
15042 {
15044 SpellShapeshiftEntry const* ssEntry = sSpellShapeshiftStore.LookupEntry(form);
15045 if (ssEntry && ssEntry->creatureType > 0)
15046 return ssEntry->creatureType;
15047 else
15049 }
15050 else
15051 return ToCreature()->GetCreatureTemplate()->type;
15052}
DBCStorage< SpellShapeshiftEntry > sSpellShapeshiftStore(SpellShapeshiftfmt)
@ CREATURE_TYPE_HUMANOID
Definition: SharedDefines.h:2606
ShapeshiftForm
Definition: Unit.h:89
ShapeshiftForm GetShapeshiftForm() const
Definition: Unit.h:2068
uint32 type
Definition: CreatureData.h:215
Definition: DBCStructure.h:1778
int32 creatureType
Definition: DBCStructure.h:1784

◆ GetCreatureTypeMask()

uint32 Unit::GetCreatureTypeMask ( ) const
inline
1527 {
1528 uint32 creatureType = GetCreatureType();
1529 return (creatureType >= 1) ? (1 << (creatureType - 1)) : 0;
1530 }
uint32 GetCreatureType() const
Definition: Unit.cpp:15039

◆ GetCritterGUID()

ObjectGuid Unit::GetCritterGUID ( ) const
inline
@ UNIT_FIELD_CRITTER
Definition: UpdateFields.h:88

◆ GetCurrentSpell() [1/2]

Spell * Unit::GetCurrentSpell ( CurrentSpellTypes  spellType) const
inline
2058{ return m_currentSpells[spellType]; }

◆ GetCurrentSpell() [2/2]

Spell * Unit::GetCurrentSpell ( uint32  spellType) const
inline
2059{ return m_currentSpells[spellType]; }

◆ GetCurrentSpellCastTime()

int32 Unit::GetCurrentSpellCastTime ( uint32  spell_id) const
4081{
4082 if (Spell const* spell = FindCurrentSpellBySpellId(spell_id))
4083 return spell->GetCastTime();
4084 return 0;
4085}
Spell * FindCurrentSpellBySpellId(uint32 spell_id) const
Definition: Unit.cpp:4072

◆ getDeathState()

DeathState Unit::getDeathState ( )
inline
1808{ return m_deathState; };

◆ GetDebugInfo()

std::string Unit::GetDebugInfo ( ) const
overridevirtual

Reimplemented from WorldObject.

21300{
21301 std::stringstream sstr;
21302 sstr << WorldObject::GetDebugInfo() << "\n"
21303 << std::boolalpha
21304 << "AliveState: " << IsAlive()
21305 << " UnitMovementFlags: " << GetUnitMovementFlags() << " ExtraUnitMovementFlags: " << GetExtraUnitMovementFlags()
21306 << " Class: " << std::to_string(getClass());
21307 return sstr.str();
21308}
std::string GetDebugInfo() const override
Definition: Object.cpp:2430

◆ GetDefaultMovementType()

MovementGeneratorType Unit::GetDefaultMovementType ( ) const
virtual

-------—End of Pet responses methods-------—

Reimplemented in Creature.

16732{
16733 return IDLE_MOTION_TYPE;
16734}
@ IDLE_MOTION_TYPE
Definition: MotionMaster.h:37

◆ GetDefenseSkillValue()

uint32 Unit::GetDefenseSkillValue ( Unit const *  target = nullptr) const
3567{
3568 if (GetTypeId() == TYPEID_PLAYER)
3569 {
3570 // in PvP use full skill instead current skill value
3571 uint32 value = (target && target->GetTypeId() == TYPEID_PLAYER)
3574 value += uint32(ToPlayer()->GetRatingBonusValue(CR_DEFENSE_SKILL));
3575 return value;
3576 }
3577 else
3578 return GetUnitMeleeSkill(target);
3579}
@ SKILL_DEFENSE
Definition: SharedDefines.h:2853
@ CR_DEFENSE_SKILL
Definition: Unit.h:405
uint16 GetSkillValue(uint32 skill) const
Definition: Player.cpp:5338
uint16 GetMaxSkillValue(uint32 skill) const
Definition: Player.cpp:5355

◆ GetDiminishing()

DiminishingLevels Unit::GetDiminishing ( DiminishingGroup  group)
14865{
14866 for (Diminishing::iterator i = m_Diminishing.begin(); i != m_Diminishing.end(); ++i)
14867 {
14868 if (i->DRGroup != group)
14869 continue;
14870
14871 if (!i->hitCount)
14872 return DIMINISHING_LEVEL_1;
14873
14874 if (!i->hitTime)
14875 return DIMINISHING_LEVEL_1;
14876
14877 // If last spell was casted more than 15 seconds ago - reset the count.
14878 if (i->stack == 0 && getMSTimeDiff(i->hitTime, GameTime::GetGameTimeMS().count()) > 15000)
14879 {
14880 i->hitCount = DIMINISHING_LEVEL_1;
14881 return DIMINISHING_LEVEL_1;
14882 }
14883 // or else increase the count.
14884 else
14885 return DiminishingLevels(i->hitCount);
14886 }
14887 return DIMINISHING_LEVEL_1;
14888}
uint32 getMSTimeDiff(uint32 oldMSTime, uint32 newMSTime)
Definition: Timer.h:110

◆ GetDirectTransport()

TransportBase * Unit::GetDirectTransport ( ) const

Returns the transport this unit is on directly (if on vehicle and transport, return vehicle)

18800{
18801 if (Vehicle* veh = GetVehicle())
18802 return veh;
18803 return GetTransport();
18804}
Vehicle * GetVehicle() const
Definition: Unit.h:2349

◆ GetDiseasesByCaster()

uint32 Unit::GetDiseasesByCaster ( ObjectGuid  casterGUID,
uint8  mode = 0 
)
5722{
5723 static const AuraType diseaseAuraTypes[] =
5724 {
5725 SPELL_AURA_PERIODIC_DAMAGE, // Frost Fever and Blood Plague
5726 SPELL_AURA_LINKED, // Crypt Fever and Ebon Plague
5728 };
5729
5730 ObjectGuid drwGUID;
5731
5732 if (Player* playerCaster = ObjectAccessor::GetPlayer(*this, casterGUID))
5733 drwGUID = playerCaster->getRuneWeaponGUID();
5734
5735 uint32 diseases = 0;
5736 for (uint8 index = 0; diseaseAuraTypes[index] != SPELL_AURA_NONE; ++index)
5737 {
5738 for (AuraEffectList::iterator i = m_modAuras[diseaseAuraTypes[index]].begin(); i != m_modAuras[diseaseAuraTypes[index]].end();)
5739 {
5740 // Get auras with disease dispel type by caster
5741 if ((*i)->GetSpellInfo()->Dispel == DISPEL_DISEASE
5742 && ((*i)->GetCasterGUID() == casterGUID || (*i)->GetCasterGUID() == drwGUID)) // if its caster or his dancing rune weapon
5743 {
5744 ++diseases;
5745
5746 if (mode == 1)
5747 {
5748 RemoveAura((*i)->GetId(), (*i)->GetCasterGUID());
5749 i = m_modAuras[diseaseAuraTypes[index]].begin();
5750 continue;
5751 }
5752 // used for glyph of scourge strike
5753 else if (mode == 2)
5754 {
5755 Aura* aura = (*i)->GetBase();
5756 if (aura && !aura->IsRemoved() && aura->GetDuration() > 0)
5757 if ((aura->GetApplyTime() + aura->GetMaxDuration() / 1000 + 8) > (GameTime::GetGameTime().count() + aura->GetDuration() / 1000))
5758 aura->SetDuration(aura->GetDuration() + 3000);
5759 }
5760 }
5761 ++i;
5762 }
5763 }
5764 return diseases;
5765}
@ DISPEL_DISEASE
Definition: SharedDefines.h:1347
AuraType
Definition: SpellAuraDefines.h:62
@ SPELL_AURA_LINKED
Definition: SpellAuraDefines.h:347
@ SPELL_AURA_NONE
Definition: SpellAuraDefines.h:63
int32 GetMaxDuration() const
Definition: SpellAuras.h:129
time_t GetApplyTime() const
Definition: SpellAuras.h:128

◆ GetDispellableAuraList()

void Unit::GetDispellableAuraList ( Unit caster,
uint32  dispelMask,
DispelChargesList dispelList 
)
5512{
5513 // we should not be able to dispel diseases if the target is affected by unholy blight
5514 if (dispelMask & (1 << DISPEL_DISEASE) && HasAura(50536))
5515 dispelMask &= ~(1 << DISPEL_DISEASE);
5516
5517 ReputationRank rank = GetReactionTo(caster, IsCharmed());
5518 bool positive = rank >= REP_FRIENDLY;
5519
5520 // Neutral unit not at war with caster should be treated as a friendly unit
5521 if (rank == REP_NEUTRAL)
5522 {
5523 if (Player* casterPlayer = caster->GetAffectingPlayer())
5524 {
5525 if (FactionTemplateEntry const* factionTemplateEntry = GetFactionTemplateEntry())
5526 {
5527 if (FactionEntry const* factionEntry = sFactionStore.LookupEntry(factionTemplateEntry->faction))
5528 {
5529 if (factionEntry->CanBeSetAtWar())
5530 {
5531 positive = !casterPlayer->GetReputationMgr().IsAtWar(factionEntry);
5532 }
5533 }
5534 }
5535 }
5536 }
5537
5538 Unit::VisibleAuraMap const* visibleAuras = GetVisibleAuras();
5539 for (Unit::VisibleAuraMap::const_iterator itr = visibleAuras->begin(); itr != visibleAuras->end(); ++itr)
5540 {
5541 Aura* aura = itr->second->GetBase();
5542
5543 // don't try to remove passive auras
5544 if (aura->IsPassive())
5545 continue;
5546
5547 if (aura->GetSpellInfo()->GetDispelMask() & dispelMask)
5548 {
5549 if (aura->GetSpellInfo()->Dispel == DISPEL_MAGIC)
5550 {
5551 // do not remove positive auras if friendly target
5552 // negative auras if non-friendly target
5553 if (itr->second->IsPositive() == positive)
5554 continue;
5555 }
5556
5557 // The charges / stack amounts don't count towards the total number of auras that can be dispelled.
5558 // Ie: A dispel on a target with 5 stacks of Winters Chill and a Polymorph has 1 / (1 + 1) -> 50% chance to dispell
5559 // Polymorph instead of 1 / (5 + 1) -> 16%.
5560 bool dispel_charges = aura->GetSpellInfo()->HasAttribute(SPELL_ATTR7_DISPEL_REMOVES_CHARGES);
5561 uint8 charges = dispel_charges ? aura->GetCharges() : aura->GetStackAmount();
5562 if (charges > 0)
5563 dispelList.push_back(std::make_pair(aura, charges));
5564 }
5565 }
5566}
@ SPELL_ATTR7_DISPEL_REMOVES_CHARGES
Definition: SharedDefines.h:623
@ REP_FRIENDLY
Definition: SharedDefines.h:156
@ DISPEL_MAGIC
Definition: SharedDefines.h:1345
uint8 GetStackAmount() const
Definition: SpellAuras.h:148
uint8 GetCharges() const
Definition: SpellAuras.h:141
bool IsPassive() const
Definition: SpellAuras.cpp:1096
uint32 Dispel
Definition: SpellInfo.h:320
bool HasAura(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, ObjectGuid itemCasterGUID=ObjectGuid::Empty, uint8 reqEffMask=0) const
Definition: Unit.cpp:5598
std::map< uint8, AuraApplication * > VisibleAuraMap
Definition: Unit.h:1312
VisibleAuraMap const * GetVisibleAuras()
Definition: Unit.h:2148

◆ GetDisplayId()

uint32 Unit::GetDisplayId ( ) const
inline

◆ GetDoTsByCaster()

uint32 Unit::GetDoTsByCaster ( ObjectGuid  casterGUID) const
5768{
5769 static const AuraType diseaseAuraTypes[] =
5770 {
5774 };
5775
5776 uint32 dots = 0;
5777 for (AuraType const* itr = &diseaseAuraTypes[0]; itr && itr[0] != SPELL_AURA_NONE; ++itr)
5778 {
5779 Unit::AuraEffectList const& auras = GetAuraEffectsByType(*itr);
5780 for (AuraEffectList::const_iterator i = auras.begin(); i != auras.end(); ++i)
5781 {
5782 // Get auras by caster
5783 if ((*i)->GetCasterGUID() == casterGUID)
5784 ++dots;
5785 }
5786 }
5787 return dots;
5788}
@ SPELL_AURA_PERIODIC_DAMAGE_PERCENT
Definition: SpellAuraDefines.h:152

◆ GetDummyAuraEffect()

AuraEffect * Unit::GetDummyAuraEffect ( SpellFamilyNames  name,
uint32  iconId,
uint8  effIndex 
) const
inline
1973{ return GetAuraEffect(SPELL_AURA_DUMMY, name, iconId, effIndex);}

◆ GetDynamicFlags()

uint32 Unit::GetDynamicFlags ( ) const
inlineoverridevirtual

Reimplemented from Object.

◆ GetDynObject()

DynamicObject * Unit::GetDynObject ( uint32  spellId)
6029{
6030 if (m_dynObj.empty())
6031 return nullptr;
6032 for (DynObjectList::const_iterator i = m_dynObj.begin(); i != m_dynObj.end(); ++i)
6033 {
6034 DynamicObject* dynObj = *i;
6035 if (dynObj->GetSpellId() == spellId)
6036 return dynObj;
6037 }
6038 return nullptr;
6039}
Definition: DynamicObject.h:35
uint32 GetSpellId() const
Definition: DynamicObject.h:58

◆ GetEffectiveResistChance()

float Unit::GetEffectiveResistChance ( Unit const *  owner,
SpellSchoolMask  schoolMask,
Unit const *  victim 
)
static
2072{
2073 float victimResistance = float(victim->GetResistance(schoolMask));
2074 if (owner)
2075 {
2076 // Xinef: pets inherit 100% of masters penetration
2077 // Xinef: excluding traps
2078 Player const* player = owner->GetSpellModOwner();
2079 if (player && owner->GetEntry() != WORLD_TRIGGER)
2080 {
2081 victimResistance += float(player->GetTotalAuraModifierByMiscMask(SPELL_AURA_MOD_TARGET_RESISTANCE, schoolMask));
2082 victimResistance -= float(player->GetSpellPenetrationItemMod());
2083 }
2084 else
2085 victimResistance += float(owner->GetTotalAuraModifierByMiscMask(SPELL_AURA_MOD_TARGET_RESISTANCE, schoolMask));
2086 }
2087
2088 victimResistance = std::max(victimResistance, 0.0f);
2089 if (owner)
2090 victimResistance += std::max((float(victim->getLevel()) - float(owner->getLevel())) * 5.0f, 0.0f);
2091
2092 static uint32 const BOSS_LEVEL = 83;
2093 static float const BOSS_RESISTANCE_CONSTANT = 510.0f;
2094 uint32 level = victim->getLevel();
2095 float resistanceConstant = 0.0f;
2096
2097 if (level == BOSS_LEVEL)
2098 resistanceConstant = BOSS_RESISTANCE_CONSTANT;
2099 else
2100 resistanceConstant = level * 5.0f;
2101
2102 return victimResistance / (victimResistance + resistanceConstant);
2103}
int32 GetSpellPenetrationItemMod() const
Definition: Player.h:1921

◆ GetExtraUnitMovementFlags()

uint16 Unit::GetExtraUnitMovementFlags ( ) const
inline
2276{ return m_movementInfo.flags2; }

◆ GetFaction()

uint32 Unit::GetFaction ( ) const
inline

◆ GetFactionReactionTo()

ReputationRank Unit::GetFactionReactionTo ( FactionTemplateEntry const *  factionTemplateEntry,
Unit const *  target 
) const
10146{
10147 // always neutral when no template entry found
10148 if (!factionTemplateEntry)
10149 return REP_NEUTRAL;
10150
10151 FactionTemplateEntry const* targetFactionTemplateEntry = target->GetFactionTemplateEntry();
10152 if (!targetFactionTemplateEntry)
10153 return REP_NEUTRAL;
10154
10155 // xinef: check forced reputation for self also
10156 if (Player const* selfPlayerOwner = GetAffectingPlayer())
10157 if (ReputationRank const* repRank = selfPlayerOwner->GetReputationMgr().GetForcedRankIfAny(target->GetFactionTemplateEntry()))
10158 return *repRank;
10159
10160 if (Player const* targetPlayerOwner = target->GetAffectingPlayer())
10161 {
10162 // check contested flags
10163 if (factionTemplateEntry->factionFlags & FACTION_TEMPLATE_FLAG_ATTACK_PVP_ACTIVE_PLAYERS
10164 && targetPlayerOwner->HasPlayerFlag(PLAYER_FLAGS_CONTESTED_PVP))
10165 return REP_HOSTILE;
10166 if (ReputationRank const* repRank = targetPlayerOwner->GetReputationMgr().GetForcedRankIfAny(factionTemplateEntry))
10167 return *repRank;
10168 if (!target->HasUnitFlag2(UNIT_FLAG2_IGNORE_REPUTATION))
10169 {
10170 if (FactionEntry const* factionEntry = sFactionStore.LookupEntry(factionTemplateEntry->faction))
10171 {
10172 if (factionEntry->CanHaveReputation())
10173 {
10174 // CvP case - check reputation, don't allow state higher than neutral when at war
10175 ReputationRank repRank = targetPlayerOwner->GetReputationMgr().GetRank(factionEntry);
10176 if (targetPlayerOwner->GetReputationMgr().IsAtWar(factionEntry))
10177 repRank = std::min(REP_NEUTRAL, repRank);
10178 return repRank;
10179 }
10180 }
10181 }
10182 }
10183
10184 // common faction based check
10185 if (factionTemplateEntry->IsHostileTo(*targetFactionTemplateEntry))
10186 return REP_HOSTILE;
10187 if (factionTemplateEntry->IsFriendlyTo(*targetFactionTemplateEntry))
10188 return REP_FRIENDLY;
10189 if (targetFactionTemplateEntry->IsFriendlyTo(*factionTemplateEntry))
10190 return REP_FRIENDLY;
10191 if (factionTemplateEntry->factionFlags & FACTION_TEMPLATE_FLAG_HATES_ALL_EXCEPT_FRIENDS)
10192 return REP_HOSTILE;
10193 // neutral by default
10194 return REP_NEUTRAL;
10195}
@ FACTION_TEMPLATE_FLAG_HATES_ALL_EXCEPT_FRIENDS
Definition: DBCEnums.h:337
@ FACTION_TEMPLATE_FLAG_ATTACK_PVP_ACTIVE_PLAYERS
Definition: DBCEnums.h:336
@ PLAYER_FLAGS_CONTESTED_PVP
Definition: Player.h:483
@ UNIT_FLAG2_IGNORE_REPUTATION
Definition: Unit.h:490

◆ GetFactionTemplateEntry()

FactionTemplateEntry const * Unit::GetFactionTemplateEntry ( ) const
9996{
9997 FactionTemplateEntry const* entry = sFactionTemplateStore.LookupEntry(GetFaction());
9998 if (!entry)
9999 {
10000 static ObjectGuid guid; // prevent repeating spam same faction problem
10001
10002 if (GetGUID() != guid)
10003 {
10004 if (Player const* player = ToPlayer())
10005 LOG_ERROR("entities.unit", "Player {} has invalid faction (faction template id) #{}", player->GetName(), GetFaction());
10006 else if (Creature const* creature = ToCreature())
10007 LOG_ERROR("entities.unit", "Creature (template id: {}) has invalid faction (faction template id) #{}", creature->GetCreatureTemplate()->Entry, GetFaction());
10008 else
10009 LOG_ERROR("entities.unit", "Unit (name={}, type={}) has invalid faction (faction template id) #{}", GetName(), uint32(GetTypeId()), GetFaction());
10010
10011 guid = GetGUID();
10012 }
10013 }
10014 return entry;
10015}
DBCStorage< FactionTemplateEntry > sFactionTemplateStore(FactionTemplateEntryfmt)
std::string const & GetName() const
Definition: Object.h:446

◆ GetFirstControlled()

Unit * Unit::GetFirstControlled ( ) const
11024{
11025 // Sequence: charmed, pet, other guardians
11026 Unit* unit = GetCharm();
11027 if (!unit)
11028 if (ObjectGuid guid = GetMinionGUID())
11029 unit = ObjectAccessor::GetUnit(*this, guid);
11030
11031 return unit;
11032}
ObjectGuid GetMinionGUID() const
Definition: Unit.h:1815

◆ GetFirstMinion()

Minion * Unit::GetFirstMinion ( ) const
10585{
10586 if (ObjectGuid pet_guid = GetMinionGUID())
10587 {
10588 if (Creature* pet = ObjectAccessor::GetCreatureOrPetOrVehicle(*this, pet_guid))
10589 if (pet->HasUnitTypeMask(UNIT_MASK_MINION))
10590 return (Minion*)pet;
10591
10592 LOG_ERROR("entities.unit", "Unit::GetFirstMinion: Minion {} not exist.", pet_guid.ToString());
10593 const_cast<Unit*>(this)->SetMinionGUID(ObjectGuid::Empty);
10594 }
10595
10596 return nullptr;
10597}
void SetMinionGUID(ObjectGuid guid)
Definition: Unit.h:1816
Creature * GetCreatureOrPetOrVehicle(WorldObject const &, ObjectGuid const)
Definition: ObjectAccessor.cpp:239

◆ GetFollowAngle()

virtual float Unit::GetFollowAngle ( ) const
inlinevirtual

Reimplemented in Minion.

2387{ return static_cast<float>(M_PI / 2); }

◆ GetGameObject()

GameObject * Unit::GetGameObject ( uint32  spellId) const
6070{
6071 for (GameObjectList::const_iterator itr = m_gameObj.begin(); itr != m_gameObj.end(); ++itr)
6072 if (GameObject* go = ObjectAccessor::GetGameObject(*this, *itr))
6073 if (go->GetSpellId() == spellId)
6074 return go;
6075
6076 return nullptr;
6077}

◆ getGender()

uint8 Unit::getGender ( ) const
inline
1426{ return GetByteValue(UNIT_FIELD_BYTES_0, 2); }

◆ GetGuardianPet()

Guardian * Unit::GetGuardianPet ( ) const
10600{
10601 if (ObjectGuid pet_guid = GetPetGUID())
10602 {
10603 if (Creature* pet = ObjectAccessor::GetCreatureOrPetOrVehicle(*this, pet_guid))
10604 if (pet->HasUnitTypeMask(UNIT_MASK_GUARDIAN))
10605 return (Guardian*)pet;
10606
10607 LOG_FATAL("entities.unit", "Unit::GetGuardianPet: Guardian {} not exist.", pet_guid.ToString());
10608 const_cast<Unit*>(this)->SetPetGUID(ObjectGuid::Empty);
10609 }
10610
10611 return nullptr;
10612}
#define LOG_FATAL(filterType__,...)
Definition: Log.h:155
Definition: TemporarySummon.h:90
void SetPetGUID(ObjectGuid guid)
Definition: Unit.h:1820
ObjectGuid GetPetGUID() const
Definition: Unit.h:1821

◆ GetHealth()

uint32 Unit::GetHealth ( ) const
inline
@ UNIT_FIELD_HEALTH
Definition: UpdateFields.h:96

◆ GetHealthGain()

int32 Unit::GetHealthGain ( int32  dVal)
14014{
14015 int32 gain = 0;
14016
14017 if (dVal == 0)
14018 return 0;
14019
14020 int32 curHealth = (int32)GetHealth();
14021
14022 int32 val = dVal + curHealth;
14023 if (val <= 0)
14024 {
14025 return -curHealth;
14026 }
14027
14028 int32 maxHealth = (int32)GetMaxHealth();
14029
14030 if (val < maxHealth)
14031 gain = dVal;
14032 else if (curHealth != maxHealth)
14033 gain = maxHealth - curHealth;
14034
14035 return gain;
14036}

◆ GetHealthPct()

float Unit::GetHealthPct ( ) const
inline
1446{ return GetMaxHealth() ? 100.f * GetHealth() / GetMaxHealth() : 0.0f; }

◆ getHostileRefMgr()

HostileRefMgr & Unit::getHostileRefMgr ( )
inline
2146{ return m_HostileRefMgr; }

◆ GetHoverHeight()

float Unit::GetHoverHeight ( ) const
inline
2382{ return IsHovering() ? GetFloatValue(UNIT_FIELD_HOVERHEIGHT) : 0.0f; }
@ UNIT_FIELD_HOVERHEIGHT
Definition: UpdateFields.h:173
bool IsHovering() const
Definition: Unit.h:2377

◆ GetInterruptMask()

uint32 Unit::GetInterruptMask ( ) const
inline
2159{ return m_interruptMask; }

◆ GetLastDamagedTargetGuid()

ObjectGuid const & Unit::GetLastDamagedTargetGuid ( ) const
inline
1570{ return _lastDamagedTargetGuid; }

◆ GetLastExtraAttackSpell()

uint32 Unit::GetLastExtraAttackSpell ( ) const
inline
1567{ return _lastExtraAttackSpell; }

◆ getLevel()

uint8 Unit::getLevel ( ) const
inline
@ UNIT_FIELD_LEVEL
Definition: UpdateFields.h:114

◆ getLevelForTarget()

uint8 Unit::getLevelForTarget ( WorldObject const *  ) const
inlineoverridevirtual

Reimplemented from WorldObject.

1419{ return getLevel(); }

◆ GetMagicHitRedirectTarget()

Unit * Unit::GetMagicHitRedirectTarget ( Unit victim,
SpellInfo const *  spellInfo 
)
10968{
10969 // Patch 1.2 notes: Spell Reflection no longer reflects abilities
10970 if (spellInfo->HasAttribute(SPELL_ATTR0_IS_ABILITY) || spellInfo->HasAttribute(SPELL_ATTR1_NO_REDIRECTION) || spellInfo->HasAttribute(SPELL_ATTR0_NO_IMMUNITIES))
10971 return victim;
10972
10974 for (Unit::AuraEffectList::const_iterator itr = magnetAuras.begin(); itr != magnetAuras.end(); ++itr)
10975 {
10976 if (Unit* magnet = (*itr)->GetBase()->GetUnitOwner())
10977 if (spellInfo->CheckExplicitTarget(this, magnet) == SPELL_CAST_OK
10978 //&& spellInfo->CheckTarget(this, magnet, false) == SPELL_CAST_OK
10979 && _IsValidAttackTarget(magnet, spellInfo)
10980 /*&& IsWithinLOSInMap(magnet)*/)
10981 {
10982 // Xinef: We should choose minimum between flight time and queue time as in reflect, however we dont know flight time at this point, use arbitrary small number
10983 magnet->m_Events.AddEvent(new RedirectSpellEvent(*magnet, victim->GetGUID(), *itr), magnet->m_Events.CalculateQueueTime(100));
10984
10985 if (magnet->IsTotem())
10986 {
10987 uint64 queueTime = magnet->m_Events.CalculateQueueTime(100);
10988 if (spellInfo->Speed > 0.0f)
10989 {
10990 float dist = GetDistance(magnet->GetPositionX(), magnet->GetPositionY(), magnet->GetPositionZ());
10991 if (dist < 5.0f)
10992 dist = 5.0f;
10993 queueTime = magnet->m_Events.CalculateTime((uint64)floor(dist / spellInfo->Speed * 1000.0f));
10994 }
10995
10996 magnet->m_Events.AddEvent(new KillMagnetEvent(*magnet), queueTime);
10997 }
10998
10999 return magnet;
11000 }
11001 }
11002 return victim;
11003}
std::uint64_t uint64
Definition: Define.h:107
@ SPELL_ATTR1_NO_REDIRECTION
Definition: SharedDefines.h:394
@ SPELL_ATTR0_IS_ABILITY
Definition: SharedDefines.h:358
@ SPELL_ATTR0_NO_IMMUNITIES
Definition: SharedDefines.h:383
@ SPELL_AURA_SPELL_MAGNET
Definition: SpellAuraDefines.h:159
Definition: TotemAI.h:48
Definition: Unit.h:2662
bool _IsValidAttackTarget(Unit const *target, SpellInfo const *bySpell, WorldObject const *obj=nullptr) const
Definition: Unit.cpp:13770
float GetDistance(WorldObject const *obj) const
Definition: Object.cpp:1245

◆ GetMaxHealth()

uint32 Unit::GetMaxHealth ( ) const
inline
@ UNIT_FIELD_MAXHEALTH
Definition: UpdateFields.h:104

◆ GetMaxNegativeAuraModifier()

int32 Unit::GetMaxNegativeAuraModifier ( AuraType  auratype) const
5850{
5851 int32 modifier = 0;
5852
5853 AuraEffectList const& mTotalAuraList = GetAuraEffectsByType(auratype);
5854 for (AuraEffectList::const_iterator i = mTotalAuraList.begin(); i != mTotalAuraList.end(); ++i)
5855 if ((*i)->GetAmount() < modifier)
5856 modifier = (*i)->GetAmount();
5857
5858 return modifier;
5859}

◆ GetMaxNegativeAuraModifierByAffectMask()

int32 Unit::GetMaxNegativeAuraModifierByAffectMask ( AuraType  auratype,
SpellInfo const *  affectedSpell 
) const
6005{
6006 int32 modifier = 0;
6007
6008 AuraEffectList const& mTotalAuraList = GetAuraEffectsByType(auratype);
6009 for (AuraEffectList::const_iterator i = mTotalAuraList.begin(); i != mTotalAuraList.end(); ++i)
6010 {
6011 if ((*i)->IsAffectedOnSpell(affectedSpell) && (*i)->GetAmount() < modifier)
6012 modifier = (*i)->GetAmount();
6013 }
6014
6015 return modifier;
6016}

◆ GetMaxNegativeAuraModifierByMiscMask()

int32 Unit::GetMaxNegativeAuraModifierByMiscMask ( AuraType  auratype,
uint32  misc_mask 
) const
5901{
5902 int32 modifier = 0;
5903
5904 AuraEffectList const& mTotalAuraList = GetAuraEffectsByType(auratype);
5905 for (AuraEffectList::const_iterator i = mTotalAuraList.begin(); i != mTotalAuraList.end(); ++i)
5906 {
5907 if ((*i)->GetMiscValue()& misc_mask && (*i)->GetAmount() < modifier)
5908 modifier = (*i)->GetAmount();
5909 }
5910
5911 return modifier;
5912}

◆ GetMaxNegativeAuraModifierByMiscValue()

int32 Unit::GetMaxNegativeAuraModifierByMiscValue ( AuraType  auratype,
int32  misc_value 
) const
5953{
5954 int32 modifier = 0;
5955
5956 AuraEffectList const& mTotalAuraList = GetAuraEffectsByType(auratype);
5957 for (AuraEffectList::const_iterator i = mTotalAuraList.begin(); i != mTotalAuraList.end(); ++i)
5958 {
5959 if ((*i)->GetMiscValue() == misc_value && (*i)->GetAmount() < modifier)
5960 modifier = (*i)->GetAmount();
5961 }
5962
5963 return modifier;
5964}

◆ GetMaxPositiveAuraModifier()

int32 Unit::GetMaxPositiveAuraModifier ( AuraType  auratype)
5836{
5837 int32 modifier = 0;
5838
5839 AuraEffectList const& mTotalAuraList = GetAuraEffectsByType(auratype);
5840 for (AuraEffectList::const_iterator i = mTotalAuraList.begin(); i != mTotalAuraList.end(); ++i)
5841 {
5842 if ((*i)->GetAmount() > modifier)
5843 modifier = (*i)->GetAmount();
5844 }
5845
5846 return modifier;
5847}

◆ GetMaxPositiveAuraModifierByAffectMask()

int32 Unit::GetMaxPositiveAuraModifierByAffectMask ( AuraType  auratype,
SpellInfo const *  affectedSpell 
) const
5991{
5992 int32 modifier = 0;
5993
5994 AuraEffectList const& mTotalAuraList = GetAuraEffectsByType(auratype);
5995 for (AuraEffectList::const_iterator i = mTotalAuraList.begin(); i != mTotalAuraList.end(); ++i)
5996 {
5997 if ((*i)->IsAffectedOnSpell(affectedSpell) && (*i)->GetAmount() > modifier)
5998 modifier = (*i)->GetAmount();
5999 }
6000
6001 return modifier;
6002}

◆ GetMaxPositiveAuraModifierByMiscMask()

int32 Unit::GetMaxPositiveAuraModifierByMiscMask ( AuraType  auratype,
uint32  misc_mask,
const AuraEffect except = nullptr 
) const
5887{
5888 int32 modifier = 0;
5889
5890 AuraEffectList const& mTotalAuraList = GetAuraEffectsByType(auratype);
5891 for (AuraEffectList::const_iterator i = mTotalAuraList.begin(); i != mTotalAuraList.end(); ++i)
5892 {
5893 if (except != (*i) && (*i)->GetMiscValue()& misc_mask && (*i)->GetAmount() > modifier)
5894 modifier = (*i)->GetAmount();
5895 }
5896
5897 return modifier;
5898}

◆ GetMaxPositiveAuraModifierByMiscValue()

int32 Unit::GetMaxPositiveAuraModifierByMiscValue ( AuraType  auratype,
int32  misc_value 
) const
5939{
5940 int32 modifier = 0;
5941
5942 AuraEffectList const& mTotalAuraList = GetAuraEffectsByType(auratype);
5943 for (AuraEffectList::const_iterator i = mTotalAuraList.begin(); i != mTotalAuraList.end(); ++i)
5944 {
5945 if ((*i)->GetMiscValue() == misc_value && (*i)->GetAmount() > modifier)
5946 modifier = (*i)->GetAmount();
5947 }
5948
5949 return modifier;
5950}

◆ GetMaxPower()

uint32 Unit::GetMaxPower ( Powers  power) const
inline
1460{ return GetUInt32Value(static_cast<uint16>(UNIT_FIELD_MAXPOWER1) + power); }
@ UNIT_FIELD_MAXPOWER1
Definition: UpdateFields.h:105

◆ GetMaxSkillValueForLevel()

uint16 Unit::GetMaxSkillValueForLevel ( Unit const *  target = nullptr) const
inline
1545{ return (target ? getLevelForTarget(target) : getLevel()) * 5; }
uint8 getLevelForTarget(WorldObject const *) const override
Definition: Unit.h:1419

◆ GetMechanicResistChance()

int32 Unit::GetMechanicResistChance ( SpellInfo const *  spell)
3076{
3077 if (!spell)
3078 return 0;
3079 int32 resist_mech = 0;
3080 for (uint8 eff = 0; eff < MAX_SPELL_EFFECTS; ++eff)
3081 {
3082 if (!spell->Effects[eff].IsEffect())
3083 break;
3084 int32 effect_mech = spell->GetEffectMechanic(eff);
3085 if (effect_mech)
3086 {
3088 if (resist_mech < temp)
3089 resist_mech = temp;
3090 }
3091 }
3092 return resist_mech;
3093}
@ SPELL_AURA_MOD_MECHANIC_RESISTANCE
Definition: SpellAuraDefines.h:180
int32 GetTotalAuraModifierByMiscValue(AuraType auratype, int32 misc_value) const
Definition: Unit.cpp:5914

◆ GetMeleeAttackPoint()

bool Unit::GetMeleeAttackPoint ( Unit attacker,
Position pos 
)
2618{
2619 if (!attacker)
2620 {
2621 return false;
2622 }
2623
2624 AttackerSet attackers = getAttackers();
2625
2626 if (attackers.size() <= 1) // if the attackers are not more than one
2627 {
2628 return false;
2629 }
2630
2631 float meleeReach = GetExactDist2d(attacker);
2632 if (meleeReach <= 0)
2633 {
2634 return false;
2635 }
2636
2637 float minAngle = 0;
2638 Unit *refUnit = nullptr;
2639 uint32 validAttackers = 0;
2640
2641 double attackerSize = attacker->GetCollisionRadius();
2642
2643 for (const auto& otherAttacker: attackers)
2644 {
2645 // if the otherAttacker is not valid, skip
2646 if (!otherAttacker || otherAttacker->GetGUID() == attacker->GetGUID() ||
2647 !otherAttacker->IsWithinMeleeRange(this) || otherAttacker->isMoving())
2648 {
2649 continue;
2650 }
2651
2652 float curretAngle = atan(attacker->GetExactDist2d(otherAttacker) / meleeReach);
2653 if (minAngle == 0 || curretAngle < minAngle)
2654 {
2655 minAngle = curretAngle;
2656 refUnit = otherAttacker;
2657 }
2658
2659 validAttackers++;
2660 }
2661
2662 if (!validAttackers || !refUnit)
2663 {
2664 return false;
2665 }
2666
2667 float contactDist = attackerSize + refUnit->GetCollisionRadius();
2668 float requiredAngle = atan(contactDist / meleeReach);
2669 float attackersAngle = atan(attacker->GetExactDist2d(refUnit) / meleeReach);
2670
2671 // in instance: the more attacker there are, the higher will be the tollerance
2672 // outside: creatures should not intersecate
2673 float angleTollerance = attacker->GetMap()->IsDungeon() ? requiredAngle - requiredAngle * tanh(validAttackers / 5.0f) : requiredAngle;
2674
2675 if (attackersAngle > angleTollerance)
2676 {
2677 return false;
2678 }
2679
2680 double angle = atan(contactDist / meleeReach);
2681
2682 float angularRadius = frand(0.1f, 0.3f) + angle;
2683 int8 direction = (urand(0, 1) ? -1 : 1);
2684 float currentAngle = GetAngle(refUnit);
2685 float absAngle = currentAngle + angularRadius * direction;
2686
2687 float x, y, z;
2688 float distance = meleeReach - GetObjectSize();
2689 GetNearPoint(attacker, x, y, z, distance, 0.0f, absAngle);
2690
2691 if (!GetMap()->CanReachPositionAndGetValidCoords(this, x, y, z, true, true))
2692 {
2693 GetNearPoint(attacker, x, y, z, distance, 0.0f, absAngle * -1); // try the other side
2694
2695 if (!GetMap()->CanReachPositionAndGetValidCoords(this, x, y, z, true, true))
2696 {
2697 return false;
2698 }
2699 }
2700
2701 pos.Relocate(x, y, z);
2702
2703 return true;
2704}
std::int8_t int8
Definition: Define.h:106
float frand(float min, float max)
Definition: Random.cpp:57
bool IsDungeon() const
Definition: Map.h:447
float GetCollisionRadius() const override
this method gets the radius of a Unit by DB if any value is defined, otherwise it gets the value by t...
Definition: Unit.cpp:21104
std::unordered_set< Unit * > AttackerSet
Definition: Unit.h:1292
AttackerSet const & getAttackers() const
Definition: Unit.h:1383
void GetNearPoint(WorldObject const *searcher, float &x, float &y, float &z, float searcher_size, float distance2d, float absAngle, float controlZ=0, Position const *startPos=nullptr) const
Definition: Object.cpp:2572
float GetExactDist2d(const float x, const float y) const
Definition: Position.h:166

◆ GetMeleeCritChanceReduction()

float Unit::GetMeleeCritChanceReduction ( ) const
inline

◆ GetMeleeCritDamageReduction()

uint32 Unit::GetMeleeCritDamageReduction ( uint32  damage) const
inline
1581{ return GetCombatRatingDamageReduction(CR_CRIT_TAKEN_MELEE, 2.2f, 33.0f, damage); }
uint32 GetCombatRatingDamageReduction(CombatRating cr, float rate, float cap, uint32 damage) const
Definition: Unit.cpp:19227

◆ GetMeleeDamageReduction()

uint32 Unit::GetMeleeDamageReduction ( uint32  damage) const
inline
1586{ return GetCombatRatingDamageReduction(CR_CRIT_TAKEN_MELEE, 2.0f, 100.0f, damage); }

◆ GetMeleeDamageSchoolMask()

virtual SpellSchoolMask Unit::GetMeleeDamageSchoolMask ( WeaponAttackType  attackType = BASE_ATTACK,
uint8  damageIndex = 0 
) const
pure virtual

Implemented in Player, and Creature.

◆ GetMeleeHitRedirectTarget()

Unit * Unit::GetMeleeHitRedirectTarget ( Unit victim,
SpellInfo const *  spellInfo = nullptr 
)
11006{
11008 for (AuraEffectList::const_iterator i = hitTriggerAuras.begin(); i != hitTriggerAuras.end(); ++i)
11009 {
11010 if (Unit* magnet = (*i)->GetBase()->GetCaster())
11011 if (_IsValidAttackTarget(magnet, spellInfo) && magnet->IsWithinLOSInMap(this)
11012 && (!spellInfo || (spellInfo->CheckExplicitTarget(this, magnet) == SPELL_CAST_OK
11013 && spellInfo->CheckTarget(this, magnet, false) == SPELL_CAST_OK)))
11014 if (roll_chance_i((*i)->GetAmount()))
11015 {
11016 (*i)->GetBase()->DropCharge(AURA_REMOVE_BY_EXPIRE);
11017 return magnet;
11018 }
11019 }
11020 return victim;
11021}
bool roll_chance_i(int chance)
Definition: Random.h:59
@ SPELL_AURA_ADD_CASTER_HIT_TRIGGER
Definition: SpellAuraDefines.h:174

◆ GetMeleeRange()

float Unit::GetMeleeRange ( Unit const *  target) const
698{
699 float range = GetCombatReach() + target->GetCombatReach() + 4.0f / 3.0f;
700 return std::max(range, NOMINAL_MELEE_RANGE);
701}
#define NOMINAL_MELEE_RANGE
Definition: ObjectDefines.h:48
float GetCombatReach() const override
Definition: Unit.h:1347

◆ GetMeleeReach()

float Unit::GetMeleeReach ( ) const
inline
1348{ float reach = m_floatValues[UNIT_FIELD_COMBATREACH]; return reach > MIN_MELEE_REACH ? reach : MIN_MELEE_REACH; }
#define MIN_MELEE_REACH
Definition: ObjectDefines.h:47

◆ GetMinionGUID()

ObjectGuid Unit::GetMinionGUID ( ) const
inline
@ UNIT_FIELD_SUMMON
Definition: UpdateFields.h:87

◆ GetModelForForm()

uint32 Unit::GetModelForForm ( ShapeshiftForm  form) const
19234{
19235 if (GetTypeId() == TYPEID_PLAYER)
19236 {
19237 switch (form)
19238 {
19239 case FORM_CAT:
19240 // Based on Hair color
19241 if (getRace() == RACE_NIGHTELF)
19242 {
19243 uint8 hairColor = GetByteValue(PLAYER_BYTES, 3);
19244 switch (hairColor)
19245 {
19246 case 7: // Violet
19247 case 8:
19248 return 29405;
19249 case 3: // Light Blue
19250 return 29406;
19251 case 0: // Green
19252 case 1: // Light Green
19253 case 2: // Dark Green
19254 return 29407;
19255 case 4: // White
19256 return 29408;
19257 default: // original - Dark Blue
19258 return 892;
19259 }
19260 }
19261 // Based on Skin color
19262 else if (getRace() == RACE_TAUREN)
19263 {
19264 uint8 skinColor = GetByteValue(PLAYER_BYTES, 0);
19265 // Male
19266 if (getGender() == GENDER_MALE)
19267 {
19268 switch (skinColor)
19269 {
19270 case 12: // White
19271 case 13:
19272 case 14:
19273 case 18: // Completly White
19274 return 29409;
19275 case 9: // Light Brown
19276 case 10:
19277 case 11:
19278 return 29410;
19279 case 6: // Brown
19280 case 7:
19281 case 8:
19282 return 29411;
19283 case 0: // Dark
19284 case 1:
19285 case 2:
19286 case 3: // Dark Grey
19287 case 4:
19288 case 5:
19289 return 29412;
19290 default: // original - Grey
19291 return 8571;
19292 }
19293 }
19294 // Female
19295 else switch (skinColor)
19296 {
19297 case 10: // White
19298 return 29409;
19299 case 6: // Light Brown
19300 case 7:
19301 return 29410;
19302 case 4: // Brown
19303 case 5:
19304 return 29411;
19305 case 0: // Dark
19306 case 1:
19307 case 2:
19308 case 3:
19309 return 29412;
19310 default: // original - Grey
19311 return 8571;
19312 }
19313 }
19315 return 892;
19316 else
19317 return 8571;
19318 case FORM_DIREBEAR:
19319 case FORM_BEAR:
19320 // Based on Hair color
19321 if (getRace() == RACE_NIGHTELF)
19322 {
19323 uint8 hairColor = GetByteValue(PLAYER_BYTES, 3);
19324 switch (hairColor)
19325 {
19326 case 0: // Green
19327 case 1: // Light Green
19328 case 2: // Dark Green
19329 return 29413; // 29415?
19330 case 6: // Dark Blue
19331 return 29414;
19332 case 4: // White
19333 return 29416;
19334 case 3: // Light Blue
19335 return 29417;
19336 default: // original - Violet
19337 return 2281;
19338 }
19339 }
19340 // Based on Skin color
19341 else if (getRace() == RACE_TAUREN)
19342 {
19343 uint8 skinColor = GetByteValue(PLAYER_BYTES, 0);
19344 // Male
19345 if (getGender() == GENDER_MALE)
19346 {
19347 switch (skinColor)
19348 {
19349 case 0: // Dark (Black)
19350 case 1:
19351 case 2:
19352 return 29418;
19353 case 3: // White
19354 case 4:
19355 case 5:
19356 case 12:
19357 case 13:
19358 case 14:
19359 return 29419;
19360 case 9: // Light Brown/Grey
19361 case 10:
19362 case 11:
19363 case 15:
19364 case 16:
19365 case 17:
19366 return 29420;
19367 case 18: // Completly White
19368 return 29421;
19369 default: // original - Brown
19370 return 2289;
19371 }
19372 }
19373 // Female
19374 else switch (skinColor)
19375 {
19376 case 0: // Dark (Black)
19377 case 1:
19378 return 29418;
19379 case 2: // White
19380 case 3:
19381 return 29419;
19382 case 6: // Light Brown/Grey
19383 case 7:
19384 case 8:
19385 case 9:
19386 return 29420;
19387 case 10: // Completly White
19388 return 29421;
19389 default: // original - Brown
19390 return 2289;
19391 }
19392 }
19394 return 2281;
19395 else
19396 return 2289;
19397 case FORM_FLIGHT:
19399 return 20857;
19400 return 20872;
19401 case FORM_FLIGHT_EPIC:
19403 return 21243;
19404 return 21244;
19405 default:
19406 break;
19407 }
19408 }
19409
19410 uint32 modelid = 0;
19411 SpellShapeshiftEntry const* formEntry = sSpellShapeshiftStore.LookupEntry(form);
19412 if (formEntry && formEntry->modelID_A)
19413 {
19414 // Take the alliance modelid as default
19415 if (GetTypeId() != TYPEID_PLAYER)
19416 return formEntry->modelID_A;
19417 else
19418 {
19420 modelid = formEntry->modelID_A;
19421 else
19422 modelid = formEntry->modelID_H;
19423
19424 // If the player is horde but there are no values for the horde modelid - take the alliance modelid
19425 if (!modelid && Player::TeamIdForRace(getRace()) == TEAM_HORDE)
19426 modelid = formEntry->modelID_A;
19427 }
19428 }
19429
19430 return modelid;
19431}
@ GENDER_MALE
Definition: SharedDefines.h:60
@ TEAM_ALLIANCE
Definition: SharedDefines.h:732
@ TEAM_HORDE
Definition: SharedDefines.h:733
@ RACE_NIGHTELF
Definition: SharedDefines.h:73
@ RACE_TAUREN
Definition: SharedDefines.h:75
@ FORM_DIREBEAR
Definition: Unit.h:98
@ FORM_FLIGHT_EPIC
Definition: Unit.h:115
@ FORM_CAT
Definition: Unit.h:91
@ FORM_FLIGHT
Definition: Unit.h:117
@ FORM_BEAR
Definition: Unit.h:95
@ PLAYER_BYTES
Definition: UpdateFields.h:181
static TeamId TeamIdForRace(uint8 race)
Definition: Player.cpp:5715
uint8 getGender() const
Definition: Unit.h:1426
uint8 getRace(bool original=false) const
Definition: Unit.cpp:21022
uint32 modelID_H
Definition: DBCStructure.h:1788
uint32 modelID_A
Definition: DBCStructure.h:1787

◆ GetModelForTotem()

uint32 Unit::GetModelForTotem ( PlayerTotemType  totemType)
19434{
19435 switch (getRace())
19436 {
19437 case RACE_ORC:
19438 {
19439 switch (totemType)
19440 {
19441 case SUMMON_TYPE_TOTEM_FIRE: // fire
19442 return 30758;
19443 case SUMMON_TYPE_TOTEM_EARTH: // earth
19444 return 30757;
19445 case SUMMON_TYPE_TOTEM_WATER: // water
19446 return 30759;
19447 case SUMMON_TYPE_TOTEM_AIR: // air
19448 return 30756;
19449 }
19450 break;
19451 }
19452 case RACE_DWARF:
19453 {
19454 switch (totemType)
19455 {
19456 case SUMMON_TYPE_TOTEM_FIRE: // fire
19457 return 30754;
19458 case SUMMON_TYPE_TOTEM_EARTH: // earth
19459 return 30753;
19460 case SUMMON_TYPE_TOTEM_WATER: // water
19461 return 30755;
19462 case SUMMON_TYPE_TOTEM_AIR: // air
19463 return 30736;
19464 }
19465 break;
19466 }
19467 case RACE_TROLL:
19468 {
19469 switch (totemType)
19470 {
19471 case SUMMON_TYPE_TOTEM_FIRE: // fire
19472 return 30762;
19473 case SUMMON_TYPE_TOTEM_EARTH: // earth
19474 return 30761;
19475 case SUMMON_TYPE_TOTEM_WATER: // water
19476 return 30763;
19477 case SUMMON_TYPE_TOTEM_AIR: // air
19478 return 30760;
19479 }
19480 break;
19481 }
19482 case RACE_TAUREN:
19483 {
19484 switch (totemType)
19485 {
19486 case SUMMON_TYPE_TOTEM_FIRE: // fire
19487 return 4589;
19488 case SUMMON_TYPE_TOTEM_EARTH: // earth
19489 return 4588;
19490 case SUMMON_TYPE_TOTEM_WATER: // water
19491 return 4587;
19492 case SUMMON_TYPE_TOTEM_AIR: // air
19493 return 4590;
19494 }
19495 break;
19496 }
19497 case RACE_DRAENEI:
19498 {
19499 switch (totemType)
19500 {
19501 case SUMMON_TYPE_TOTEM_FIRE: // fire
19502 return 19074;
19503 case SUMMON_TYPE_TOTEM_EARTH: // earth
19504 return 19073;
19505 case SUMMON_TYPE_TOTEM_WATER: // water
19506 return 19075;
19507 case SUMMON_TYPE_TOTEM_AIR: // air
19508 return 19071;
19509 }
19510 break;
19511 }
19512 default: // One standard for other races.
19513 {
19514 switch (totemType)
19515 {
19516 case SUMMON_TYPE_TOTEM_FIRE: // fire
19517 return 4589;
19518 case SUMMON_TYPE_TOTEM_EARTH: // earth
19519 return 4588;
19520 case SUMMON_TYPE_TOTEM_WATER: // water
19521 return 4587;
19522 case SUMMON_TYPE_TOTEM_AIR: // air
19523 return 4590;
19524 }
19525 break;
19526 }
19527 }
19528 return 0;
19529}
@ RACE_TROLL
Definition: SharedDefines.h:77
@ RACE_ORC
Definition: SharedDefines.h:71
@ RACE_DRAENEI
Definition: SharedDefines.h:80
@ RACE_DWARF
Definition: SharedDefines.h:72
@ SUMMON_TYPE_TOTEM_EARTH
Definition: Unit.h:1222
@ SUMMON_TYPE_TOTEM_WATER
Definition: Unit.h:1223
@ SUMMON_TYPE_TOTEM_FIRE
Definition: Unit.h:1221
@ SUMMON_TYPE_TOTEM_AIR
Definition: Unit.h:1224

◆ GetModifierValue()

float Unit::GetModifierValue ( UnitMods  unitMod,
UnitModifierType  modifierType 
) const
15146{
15147 if (unitMod >= UNIT_MOD_END || modifierType >= MODIFIER_TYPE_END)
15148 {
15149 LOG_ERROR("entities.unit", "attempt to access non-existing modifier value from UnitMods!");
15150 return 0.0f;
15151 }
15152
15153 if (modifierType == TOTAL_PCT && m_auraModifiersGroup[unitMod][modifierType] <= 0.0f)
15154 return 0.0f;
15155
15156 return m_auraModifiersGroup[unitMod][modifierType];
15157}
@ MODIFIER_TYPE_END
Definition: Unit.h:249

◆ GetMotionMaster() [1/2]

MotionMaster * Unit::GetMotionMaster ( )
inline
2257{ return i_motionMaster; }

◆ GetMotionMaster() [2/2]

const MotionMaster * Unit::GetMotionMaster ( ) const
inline
2258{ return i_motionMaster; }

◆ GetMountID()

uint32 Unit::GetMountID ( ) const
inline

◆ GetNativeDisplayId()

uint32 Unit::GetNativeDisplayId ( ) const
inline
@ UNIT_FIELD_NATIVEDISPLAYID
Definition: UpdateFields.h:125

◆ GetNegStat()

float Unit::GetNegStat ( Stats  stat) const
inline
2041{ return GetFloatValue(static_cast<uint16>(UNIT_FIELD_NEGSTAT0) + stat); }

◆ GetNextRandomRaidMemberOrPet()

Unit * Unit::GetNextRandomRaidMemberOrPet ( float  radius)
11063{
11064 Player* player = nullptr;
11065 if (GetTypeId() == TYPEID_PLAYER)
11066 player = ToPlayer();
11067 // Should we enable this also for charmed units?
11068 else if (GetTypeId() == TYPEID_UNIT && IsPet())
11069 player = GetOwner()->ToPlayer();
11070
11071 if (!player)
11072 return nullptr;
11073 Group* group = player->GetGroup();
11074 // When there is no group check pet presence
11075 if (!group)
11076 {
11077 // We are pet now, return owner
11078 if (player != this)
11079 return IsWithinDistInMap(player, radius) ? player : nullptr;
11080 Unit* pet = GetGuardianPet();
11081 // No pet, no group, nothing to return
11082 if (!pet)
11083 return nullptr;
11084 // We are owner now, return pet
11085 return IsWithinDistInMap(pet, radius) ? pet : nullptr;
11086 }
11087
11088 std::vector<Unit*> nearMembers;
11089 // reserve place for players and pets because resizing vector every unit push is unefficient (vector is reallocated then)
11090 nearMembers.reserve(group->GetMembersCount() * 2);
11091
11092 for (GroupReference* itr = group->GetFirstMember(); itr != nullptr; itr = itr->next())
11093 if (Player* Target = itr->GetSource())
11094 {
11095 if (Target != this && !IsWithinDistInMap(Target, radius))
11096 continue;
11097
11098 // IsHostileTo check duel and controlled by enemy
11099 if (Target != this && Target->IsAlive() && !IsHostileTo(Target))
11100 nearMembers.push_back(Target);
11101
11102 // Push player's pet to vector
11103 if (Unit* pet = Target->GetGuardianPet())
11104 if (pet != this && pet->IsAlive() && IsWithinDistInMap(pet, radius) && !IsHostileTo(pet))
11105 nearMembers.push_back(pet);
11106 }
11107
11108 if (nearMembers.empty())
11109 return nullptr;
11110
11111 uint32 randTarget = urand(0, nearMembers.size() - 1);
11112 return nearMembers[randTarget];
11113}
Definition: Group.h:168
uint32 GetMembersCount() const
Definition: Group.h:243
GroupReference * GetFirstMember()
Definition: Group.h:241
Definition: GroupReference.h:27
GroupReference * next()
Definition: GroupReference.h:36
Group * GetGroup()
Definition: Player.h:2417
Guardian * GetGuardianPet() const
Definition: Unit.cpp:10599
bool IsWithinDistInMap(WorldObject const *obj, float dist2compare, bool is3D=true, bool useBoundingRadius=true) const
Definition: Object.cpp:1321

◆ GetNpcFlags()

NPCFlags Unit::GetNpcFlags ( ) const
inline
NPCFlags
Non Player Character flags.
Definition: Unit.h:514

◆ GetOwnedAura()

Aura * Unit::GetOwnedAura ( uint32  spellId,
ObjectGuid  casterGUID = ObjectGuid::Empty,
ObjectGuid  itemCasterGUID = ObjectGuid::Empty,
uint8  reqEffMask = 0,
Aura except = nullptr 
) const
4681{
4682 AuraMapBounds range = m_ownedAuras.equal_range(spellId);
4683 for (AuraMap::const_iterator itr = range.first; itr != range.second; ++itr)
4684 {
4685 if (((itr->second->GetEffectMask() & reqEffMask) == reqEffMask)
4686 && (!casterGUID || itr->second->GetCasterGUID() == casterGUID)
4687 && (!itemCasterGUID || itr->second->GetCastItemGUID() == itemCasterGUID)
4688 && (!except || except != itr->second))
4689 {
4690 return itr->second;
4691 }
4692 }
4693 return nullptr;
4694}
std::pair< AuraMap::const_iterator, AuraMap::const_iterator > AuraMapBounds
Definition: Unit.h:1296

◆ GetOwnedAuras() [1/2]

AuraMap & Unit::GetOwnedAuras ( )
inline
1911{ return m_ownedAuras; }

◆ GetOwnedAuras() [2/2]

AuraMap const & Unit::GetOwnedAuras ( ) const
inline
1912{ return m_ownedAuras; }

◆ GetOwner()

Unit * Unit::GetOwner ( ) const
10549{
10550 if (ObjectGuid ownerGUID = GetOwnerGUID())
10551 return ObjectAccessor::GetUnit(*this, ownerGUID);
10552
10553 return nullptr;
10554}

◆ GetOwnerGUID()

ObjectGuid Unit::GetOwnerGUID ( ) const
inline
@ UNIT_FIELD_SUMMONEDBY
Definition: UpdateFields.h:90

◆ GetPartyMembers()

void Unit::GetPartyMembers ( std::list< Unit * > &  units)
18852{
18853 Unit* owner = GetCharmerOrOwnerOrSelf();
18854 Group* group = nullptr;
18855 if (owner->GetTypeId() == TYPEID_PLAYER)
18856 group = owner->ToPlayer()->GetGroup();
18857
18858 if (group)
18859 {
18860 uint8 subgroup = owner->ToPlayer()->GetSubGroup();
18861
18862 for (GroupReference* itr = group->GetFirstMember(); itr != nullptr; itr = itr->next())
18863 {
18864 Player* Target = itr->GetSource();
18865
18866 // IsHostileTo check duel and controlled by enemy
18867 if (Target && Target->IsInMap(owner) && Target->GetSubGroup() == subgroup && !IsHostileTo(Target))
18868 {
18869 if (Target->IsAlive())
18870 TagUnitMap.push_back(Target);
18871
18872 for (Unit::ControlSet::iterator iterator = Target->m_Controlled.begin(); iterator != Target->m_Controlled.end(); ++iterator)
18873 {
18874 if (Unit* pet = *iterator)
18875 if (pet->IsGuardian() && pet->IsAlive())
18876 TagUnitMap.push_back(pet);
18877 }
18878 }
18879 }
18880 }
18881 else
18882 {
18883 if (owner->IsAlive())
18884 TagUnitMap.push_back(owner);
18885
18886 for (Unit::ControlSet::iterator itr = owner->m_Controlled.begin(); itr != owner->m_Controlled.end(); ++itr)
18887 {
18888 if (Unit* pet = *itr)
18889 if (pet->IsGuardian() && pet->IsAlive())
18890 TagUnitMap.push_back(pet);
18891 }
18892 }
18893}
uint8 GetSubGroup() const
Definition: Player.h:2421

◆ GetPetGUID()

ObjectGuid Unit::GetPetGUID ( ) const
inline
1821{ return m_SummonSlot[SUMMON_SLOT_PET]; }
#define SUMMON_SLOT_PET
Definition: Unit.h:1210

◆ GetPhaseByAuras()

uint32 Unit::GetPhaseByAuras ( ) const
19071{
19072 uint32 currentPhase = 0;
19074 if (!phases.empty())
19075 for (AuraEffectList::const_iterator itr = phases.begin(); itr != phases.end(); ++itr)
19076 currentPhase |= (*itr)->GetMiscValue();
19077
19078 return currentPhase;
19079}
@ SPELL_AURA_PHASE
Definition: SpellAuraDefines.h:324

◆ GetPosStat()

float Unit::GetPosStat ( Stats  stat) const
inline
2040{ return GetFloatValue(static_cast<uint16>(UNIT_FIELD_POSSTAT0) + stat); }

◆ GetPower()

uint32 Unit::GetPower ( Powers  power) const
inline
1459{ return GetUInt32Value(static_cast<uint16>(UNIT_FIELD_POWER1) + power); }
@ UNIT_FIELD_POWER1
Definition: UpdateFields.h:97

◆ GetPowerPct()

float Unit::GetPowerPct ( Powers  power) const
inline
1449{ return GetMaxPower(power) ? 100.f * GetPower(power) / GetMaxPower(power) : 0.0f; }
uint32 GetMaxPower(Powers power) const
Definition: Unit.h:1460
uint32 GetPower(Powers power) const
Definition: Unit.h:1459

◆ getPowerType()

Powers Unit::getPowerType ( ) const
inline
1457{ return Powers(GetByteValue(UNIT_FIELD_BYTES_0, 3)); }
Powers
Definition: SharedDefines.h:240

◆ GetPowerTypeByAuraGroup()

Powers Unit::GetPowerTypeByAuraGroup ( UnitMods  unitMod) const
15264{
15265 switch (unitMod)
15266 {
15267 case UNIT_MOD_RAGE:
15268 return POWER_RAGE;
15269 case UNIT_MOD_FOCUS:
15270 return POWER_FOCUS;
15271 case UNIT_MOD_ENERGY:
15272 return POWER_ENERGY;
15273 case UNIT_MOD_HAPPINESS:
15274 return POWER_HAPPINESS;
15275 case UNIT_MOD_RUNE:
15276 return POWER_RUNE;
15278 return POWER_RUNIC_POWER;
15279 default:
15280 case UNIT_MOD_MANA:
15281 return POWER_MANA;
15282 }
15283}
@ UNIT_MOD_RUNE
Definition: Unit.h:273
@ UNIT_MOD_ENERGY
Definition: Unit.h:271
@ UNIT_MOD_FOCUS
Definition: Unit.h:270
@ UNIT_MOD_HAPPINESS
Definition: Unit.h:272
@ UNIT_MOD_MANA
Definition: Unit.h:268
@ UNIT_MOD_RAGE
Definition: Unit.h:269
@ UNIT_MOD_RUNIC_POWER
Definition: Unit.h:274

◆ GetPPMProcChance()

float Unit::GetPPMProcChance ( uint32  WeaponSpeed,
float  PPM,
SpellInfo const *  spellProto 
) const
13356{
13357 // proc per minute chance calculation
13358 if (PPM <= 0)
13359 return 0.0f;
13360
13361 // Apply chance modifer aura
13362 if (spellProto)
13363 if (Player* modOwner = GetSpellModOwner())
13364 modOwner->ApplySpellMod(spellProto->Id, SPELLMOD_PROC_PER_MINUTE, PPM);
13365
13366 return floor((WeaponSpeed * PPM) / 600.0f); // result is chance in percents (probability = Speed_in_sec * (PPM / 60))
13367}
@ SPELLMOD_PROC_PER_MINUTE
Definition: SpellDefines.h:103

◆ GetProcAurasTriggeredOnEvent()

void Unit::GetProcAurasTriggeredOnEvent ( std::list< AuraApplication * > &  aurasTriggeringProc,
std::list< AuraApplication * > *  procAuras,
ProcEventInfo  eventInfo 
)
16618{
16619 // use provided list of auras which can proc
16620 if (procAuras)
16621 {
16622 for (std::list<AuraApplication*>::iterator itr = procAuras->begin(); itr != procAuras->end(); ++itr)
16623 {
16624 ASSERT((*itr)->GetTarget() == this);
16625 if (!(*itr)->GetRemoveMode())
16626 if ((*itr)->GetBase()->IsProcTriggeredOnEvent(*itr, eventInfo))
16627 {
16628 (*itr)->GetBase()->PrepareProcToTrigger(*itr, eventInfo);
16629 aurasTriggeringProc.push_back(*itr);
16630 }
16631 }
16632 }
16633 // or generate one on our own
16634 else
16635 {
16636 for (AuraApplicationMap::iterator itr = GetAppliedAuras().begin(); itr != GetAppliedAuras().end(); ++itr)
16637 {
16638 if (itr->second->GetBase()->IsProcTriggeredOnEvent(itr->second, eventInfo))
16639 {
16640 itr->second->GetBase()->PrepareProcToTrigger(itr->second, eventInfo);
16641 aurasTriggeringProc.push_back(itr->second);
16642 }
16643 }
16644 }
16645}

◆ getRace()

uint8 Unit::getRace ( bool  original = false) const
21023{
21024 if (GetTypeId() == TYPEID_PLAYER)
21025 {
21026 if (original)
21027 return m_realRace;
21028 else
21029 return m_race;
21030 }
21031
21033}

◆ getRaceMask()

uint32 Unit::getRaceMask ( ) const
inline
1423{ return 1 << (getRace(true) - 1); }

◆ GetRandomContactPoint()

bool Unit::GetRandomContactPoint ( Unit const *  target,
float &  x,
float &  y,
float &  z,
bool  force = false 
) const
719{
720 float combat_reach = GetCombatReach();
721 if (combat_reach < 0.1f) // sometimes bugged for players
722 combat_reach = DEFAULT_COMBAT_REACH;
723
724 uint32 attacker_number = getAttackers().size();
725 if (attacker_number > 0)
726 --attacker_number;
727 Creature const* c = obj->ToCreature();
728 if (c)
729 if (c->isWorldBoss() || c->IsDungeonBoss() || (obj->IsPet() && const_cast<Unit*>(obj)->ToPet()->isControlled()))
730 attacker_number = 0; // pussywizard: pets and bosses just come to target from their angle
731
732 GetNearPoint(obj, x, y, z, isMoving() ? (obj->GetCombatReach() > 7.75f ? obj->GetCombatReach() - 7.5f : 0.25f) : obj->GetCombatReach(), 0.0f,
733 GetAngle(obj) + (attacker_number ? (static_cast<float>(M_PI / 2) - static_cast<float>(M_PI) * (float)rand_norm()) * float(attacker_number) / combat_reach * 0.3f : 0));
734
735 // pussywizard
736 if (std::fabs(this->GetPositionZ() - z) > this->GetCollisionHeight() || !IsWithinLOS(x, y, z))
737 {
738 x = this->GetPositionX();
739 y = this->GetPositionY();
740 z = this->GetPositionZ();
741 obj->UpdateAllowedPositionZ(x, y, z);
742 }
743 float maxDist = GetMeleeRange(obj);
744 if (GetExactDistSq(x, y, z) >= maxDist * maxDist)
745 {
746 if (force)
747 {
748 x = this->GetPositionX();
749 y = this->GetPositionY();
750 z = this->GetPositionZ();
751 return true;
752 }
753 return false;
754 }
755 return true;
756}
#define DEFAULT_COMBAT_REACH
Definition: ObjectDefines.h:46
bool IsDungeonBoss() const
Definition: Creature.cpp:3035
bool isControlled() const
Definition: Pet.h:52
float GetCollisionHeight() const override
Return collision height sent to client.
Definition: Unit.cpp:21110
float GetMeleeRange(Unit const *target) const
Definition: Unit.cpp:697
bool IsWithinLOS(float x, float y, float z, VMAP::ModelIgnoreFlags ignoreFlags=VMAP::ModelIgnoreFlags::Nothing, LineOfSightChecks checks=LINEOFSIGHT_ALL_CHECKS) const
Definition: Object.cpp:1326
float GetExactDistSq(float x, float y, float z) const
Definition: Position.h:170

◆ GetRangedCritChanceReduction()

float Unit::GetRangedCritChanceReduction ( ) const
inline

◆ GetRangedCritDamageReduction()

uint32 Unit::GetRangedCritDamageReduction ( uint32  damage) const
inline
1582{ return GetCombatRatingDamageReduction(CR_CRIT_TAKEN_RANGED, 2.2f, 33.0f, damage); }

◆ GetRangedDamageReduction()

uint32 Unit::GetRangedDamageReduction ( uint32  damage) const
inline
1587{ return GetCombatRatingDamageReduction(CR_CRIT_TAKEN_RANGED, 2.0f, 100.0f, damage); }

◆ GetReactionTo()

ReputationRank Unit::GetReactionTo ( Unit const *  target,
bool  checkOriginalFaction = false 
) const
10026{
10027 // always friendly to self
10028 if (this == target)
10029 return REP_FRIENDLY;
10030
10031 // always friendly to charmer or owner
10033 return REP_FRIENDLY;
10034
10035 Player const* selfPlayerOwner = GetAffectingPlayer();
10036 Player const* targetPlayerOwner = target->GetAffectingPlayer();
10037
10038 // check forced reputation to support SPELL_AURA_FORCE_REACTION
10039 if (selfPlayerOwner)
10040 {
10041 if (FactionTemplateEntry const* targetFactionTemplateEntry = target->GetFactionTemplateEntry())
10042 if (ReputationRank const* repRank = selfPlayerOwner->GetReputationMgr().GetForcedRankIfAny(targetFactionTemplateEntry))
10043 return *repRank;
10044 }
10045 else if (targetPlayerOwner)
10046 {
10047 if (FactionTemplateEntry const* selfFactionTemplateEntry = GetFactionTemplateEntry())
10048 if (ReputationRank const* repRank = targetPlayerOwner->GetReputationMgr().GetForcedRankIfAny(selfFactionTemplateEntry))
10049 return *repRank;
10050 }
10051
10053 {
10054 if (target->HasUnitFlag(UNIT_FLAG_PLAYER_CONTROLLED))
10055 {
10056 if (selfPlayerOwner && targetPlayerOwner)
10057 {
10058 // always friendly to other unit controlled by player, or to the player himself
10059 if (selfPlayerOwner == targetPlayerOwner)
10060 return REP_FRIENDLY;
10061
10062 // duel - always hostile to opponent
10063 if (selfPlayerOwner->duel && selfPlayerOwner->duel->Opponent == targetPlayerOwner && selfPlayerOwner->duel->State == DUEL_STATE_IN_PROGRESS)
10064 return REP_HOSTILE;
10065
10066 // same group - checks dependant only on our faction - skip FFA_PVP for example
10067 if (selfPlayerOwner->IsInRaidWith(targetPlayerOwner))
10068 return REP_FRIENDLY; // return true to allow config option AllowTwoSide.Interaction.Group to work
10069 // however client seems to allow mixed group parties, because in 13850 client it works like:
10070 // return GetFactionReactionTo(GetFactionTemplateEntry(), target);
10071 }
10072
10073 // check FFA_PVP
10074 if (IsFFAPvP() && target->IsFFAPvP())
10075 return REP_HOSTILE;
10076
10077 if (selfPlayerOwner)
10078 {
10079 if (FactionTemplateEntry const* targetFactionTemplateEntry = target->GetFactionTemplateEntry())
10080 {
10081 if (ReputationRank const* repRank = selfPlayerOwner->GetReputationMgr().GetForcedRankIfAny(targetFactionTemplateEntry))
10082 return *repRank;
10083 if (!selfPlayerOwner->HasUnitFlag2(UNIT_FLAG2_IGNORE_REPUTATION))
10084 {
10085 if (FactionEntry const* targetFactionEntry = sFactionStore.LookupEntry(targetFactionTemplateEntry->faction))
10086 {
10087 if (targetFactionEntry->CanHaveReputation())
10088 {
10089 // check contested flags
10090 if (targetFactionTemplateEntry->factionFlags & FACTION_TEMPLATE_FLAG_ATTACK_PVP_ACTIVE_PLAYERS
10091 && selfPlayerOwner->HasPlayerFlag(PLAYER_FLAGS_CONTESTED_PVP))
10092 return REP_HOSTILE;
10093
10094 // if faction has reputation, hostile state depends only from AtWar state
10095 if (selfPlayerOwner->GetReputationMgr().IsAtWar(targetFactionEntry))
10096 return REP_HOSTILE;
10097 return REP_FRIENDLY;
10098 }
10099 }
10100 }
10101 }
10102 }
10103 }
10104 }
10105
10106 ReputationRank repRank = REP_HATED;
10107 if (!sScriptMgr->IfNormalReaction(this, target, repRank))
10108 {
10109 return ReputationRank(repRank);
10110 }
10111
10112 FactionTemplateEntry const* factionTemplateEntry = nullptr;
10113 if (checkOriginalFaction)
10114 {
10115 if (GetTypeId() == TYPEID_PLAYER)
10116 {
10117 if (ChrRacesEntry const* rEntry = sChrRacesStore.LookupEntry(getRace()))
10118 {
10119 factionTemplateEntry = sFactionTemplateStore.LookupEntry(rEntry->FactionID);
10120 }
10121 }
10122 else
10123 {
10124 Unit* owner = GetOwner();
10125 if (HasUnitTypeMask(UNIT_MASK_MINION) && owner)
10126 {
10127 factionTemplateEntry = sFactionTemplateStore.LookupEntry(owner->GetFaction());
10128 }
10129 else if (CreatureTemplate const* cinfo = ToCreature()->GetCreatureTemplate())
10130 {
10131 factionTemplateEntry = sFactionTemplateStore.LookupEntry(cinfo->faction);
10132 }
10133 }
10134 }
10135
10136 if (!factionTemplateEntry)
10137 {
10138 factionTemplateEntry = GetFactionTemplateEntry();
10139 }
10140
10141 // do checks dependant only on our faction
10142 return GetFactionReactionTo(factionTemplateEntry, target);
10143}
DBCStorage< ChrRacesEntry > sChrRacesStore(ChrRacesEntryfmt)
@ REP_HATED
Definition: SharedDefines.h:152
bool HasPlayerFlag(PlayerFlags flags) const
Definition: Player.h:1090
bool IsAtWar(uint32 faction_id) const
Definition: ReputationMgr.cpp:55
ReputationRank GetFactionReactionTo(FactionTemplateEntry const *factionTemplateEntry, Unit const *target) const
Definition: Unit.cpp:10145
Definition: DBCStructure.h:679

◆ GetRedirectThreatPercent()

uint32 Unit::GetRedirectThreatPercent ( )
inline
uint32 GetThreatPct() const
Definition: Unit.h:954

◆ GetRedirectThreatTarget()

Unit * Unit::GetRedirectThreatTarget ( ) const
19532{
19534}
ObjectGuid GetTargetGUID() const
Definition: Unit.h:953

◆ GetResistance() [1/2]

uint32 Unit::GetResistance ( SpellSchoolMask  mask) const
20324{
20325 int32 resist = -1;
20326 for (int i = SPELL_SCHOOL_NORMAL; i < MAX_SPELL_SCHOOL; ++i)
20327 if (mask & (1 << i) && (resist < 0 || resist > int32(GetResistance(SpellSchools(i)))))
20328 resist = int32(GetResistance(SpellSchools(i)));
20329
20330 // resist value will never be negative here
20331 return uint32(resist);
20332}

◆ GetResistance() [2/2]

uint32 Unit::GetResistance ( SpellSchools  school) const
inline
1433{ return GetUInt32Value(static_cast<uint16>(UNIT_FIELD_RESISTANCES) + school); }
@ UNIT_FIELD_RESISTANCES
Definition: UpdateFields.h:156

◆ GetResistanceBuffMods()

float Unit::GetResistanceBuffMods ( SpellSchools  school,
bool  positive 
) const
inline
2022{ return GetFloatValue(positive ? static_cast<uint16>(UNIT_FIELD_RESISTANCEBUFFMODSPOSITIVE) + school : static_cast<uint16>(UNIT_FIELD_RESISTANCEBUFFMODSNEGATIVE) + + school); }

◆ GetShapeshiftForm()

ShapeshiftForm Unit::GetShapeshiftForm ( ) const
inline

◆ GetSharedVisionList()

SharedVisionList const & Unit::GetSharedVisionList ( )
inline
1886{ return m_sharedVision; }

◆ GetSheath()

SheathState Unit::GetSheath ( ) const
inline
SheathState
Definition: Unit.h:125

◆ GetShieldBlockValue() [1/2]

virtual uint32 Unit::GetShieldBlockValue ( ) const
pure virtual

Implemented in Creature, and Player.

◆ GetShieldBlockValue() [2/2]

uint32 Unit::GetShieldBlockValue ( uint32  soft_cap,
uint32  hard_cap 
) const
inline
1620 {
1621 uint32 value = GetShieldBlockValue();
1622 if (value >= hard_cap)
1623 {
1624 value = (soft_cap + hard_cap) / 2;
1625 }
1626 else if (value > soft_cap)
1627 {
1628 value = soft_cap + ((value - soft_cap) / 2);
1629 }
1630
1631 return value;
1632 }

◆ GetSingleCastAuras() [1/2]

AuraList & Unit::GetSingleCastAuras ( )
inline
1965{ return m_scAuras; }
AuraList m_scAuras
Definition: Unit.h:2503

◆ GetSingleCastAuras() [2/2]

AuraList const & Unit::GetSingleCastAuras ( ) const
inline
1966{ return m_scAuras; }

◆ GetSpeed()

float Unit::GetSpeed ( UnitMoveType  mtype) const
14297{
14298 return m_speed_rate[mtype] * (IsControlledByPlayer() ? playerBaseMoveSpeed[mtype] : baseMoveSpeed[mtype]);
14299}
float baseMoveSpeed[MAX_MOVE_TYPE]
Definition: Unit.cpp:75
float playerBaseMoveSpeed[MAX_MOVE_TYPE]
Definition: Unit.cpp:88

◆ GetSpeedRate()

float Unit::GetSpeedRate ( UnitMoveType  mtype) const
inline
2243{ return m_speed_rate[mtype]; }

◆ GetSpellCritChanceReduction()

float Unit::GetSpellCritChanceReduction ( ) const
inline

◆ GetSpellCritDamageReduction()

uint32 Unit::GetSpellCritDamageReduction ( uint32  damage) const
inline
1583{ return GetCombatRatingDamageReduction(CR_CRIT_TAKEN_SPELL, 2.2f, 33.0f, damage); }

◆ GetSpellDamageReduction()

uint32 Unit::GetSpellDamageReduction ( uint32  damage) const
inline
1588{ return GetCombatRatingDamageReduction(CR_CRIT_TAKEN_SPELL, 2.0f, 100.0f, damage); }

◆ GetSpellMaxRangeForTarget()

float Unit::GetSpellMaxRangeForTarget ( Unit const *  target,
SpellInfo const *  spellInfo 
) const
15005{
15006 if (!spellInfo->RangeEntry)
15007 {
15008 return 0;
15009 }
15010
15011 if (spellInfo->RangeEntry->RangeMax[1] == spellInfo->RangeEntry->RangeMax[0])
15012 {
15013 return spellInfo->GetMaxRange();
15014 }
15015
15016 if (!target)
15017 {
15018 return spellInfo->GetMaxRange(true);
15019 }
15020
15021 return spellInfo->GetMaxRange(!IsHostileTo(target));
15022}

◆ GetSpellMinRangeForTarget()

float Unit::GetSpellMinRangeForTarget ( Unit const *  target,
SpellInfo const *  spellInfo 
) const
15025{
15026 if (!spellInfo->RangeEntry)
15027 {
15028 return 0;
15029 }
15030
15031 if (spellInfo->RangeEntry->RangeMin[1] == spellInfo->RangeEntry->RangeMin[0])
15032 {
15033 return spellInfo->GetMinRange();
15034 }
15035
15036 return spellInfo->GetMinRange(!IsHostileTo(target));
15037}

◆ GetSpellModOwner()

Player * Unit::GetSpellModOwner ( ) const
16682{
16683 if (Player* player = const_cast<Unit*>(this)->ToPlayer())
16684 return player;
16685
16686 if (Unit* owner = GetOwner())
16687 if (Player* player = owner->ToPlayer())
16688 return player;
16689
16690 return nullptr;
16691}

◆ GetSpellSchoolByAuraGroup()

SpellSchools Unit::GetSpellSchoolByAuraGroup ( UnitMods  unitMod) const
15203{
15205
15206 switch (unitMod)
15207 {
15209 school = SPELL_SCHOOL_HOLY;
15210 break;
15212 school = SPELL_SCHOOL_FIRE;
15213 break;
15215 school = SPELL_SCHOOL_NATURE;
15216 break;
15218 school = SPELL_SCHOOL_FROST;
15219 break;
15221 school = SPELL_SCHOOL_SHADOW;
15222 break;
15224 school = SPELL_SCHOOL_ARCANE;
15225 break;
15226
15227 default:
15228 break;
15229 }
15230
15231 return school;
15232}
@ SPELL_SCHOOL_SHADOW
Definition: SharedDefines.h:260
@ SPELL_SCHOOL_NATURE
Definition: SharedDefines.h:258
@ SPELL_SCHOOL_FROST
Definition: SharedDefines.h:259
@ SPELL_SCHOOL_ARCANE
Definition: SharedDefines.h:261
@ SPELL_SCHOOL_FIRE
Definition: SharedDefines.h:257
@ SPELL_SCHOOL_HOLY
Definition: SharedDefines.h:256
@ UNIT_MOD_RESISTANCE_SHADOW
Definition: Unit.h:280
@ UNIT_MOD_RESISTANCE_FROST
Definition: Unit.h:279
@ UNIT_MOD_RESISTANCE_HOLY
Definition: Unit.h:276
@ UNIT_MOD_RESISTANCE_ARCANE
Definition: Unit.h:281
@ UNIT_MOD_RESISTANCE_FIRE
Definition: Unit.h:277
@ UNIT_MOD_RESISTANCE_NATURE
Definition: Unit.h:278

◆ getStandState()

uint8 Unit::getStandState ( ) const
inline
1532{ return GetByteValue(UNIT_FIELD_BYTES_1, 0); }
@ UNIT_FIELD_BYTES_1
Definition: UpdateFields.h:131

◆ GetStat()

float Unit::GetStat ( Stats  stat) const
inline
1428{ return float(GetUInt32Value(static_cast<uint16>(UNIT_FIELD_STAT0) + stat)); }
@ UNIT_FIELD_STAT0
Definition: UpdateFields.h:141

◆ GetStatByAuraGroup()

Stats Unit::GetStatByAuraGroup ( UnitMods  unitMod) const
15235{
15236 Stats stat = STAT_STRENGTH;
15237
15238 switch (unitMod)
15239 {
15241 stat = STAT_STRENGTH;
15242 break;
15244 stat = STAT_AGILITY;
15245 break;
15247 stat = STAT_STAMINA;
15248 break;
15250 stat = STAT_INTELLECT;
15251 break;
15253 stat = STAT_SPIRIT;
15254 break;
15255
15256 default:
15257 break;
15258 }
15259
15260 return stat;
15261}
Stats
Definition: SharedDefines.h:229
@ STAT_SPIRIT
Definition: SharedDefines.h:234
@ STAT_INTELLECT
Definition: SharedDefines.h:233
@ STAT_AGILITY
Definition: SharedDefines.h:231
@ STAT_STRENGTH
Definition: SharedDefines.h:230
@ STAT_STAMINA
Definition: SharedDefines.h:232
@ UNIT_MOD_STAT_INTELLECT
Definition: Unit.h:265
@ UNIT_MOD_STAT_SPIRIT
Definition: Unit.h:266
@ UNIT_MOD_STAT_STRENGTH
Definition: Unit.h:262
@ UNIT_MOD_STAT_AGILITY
Definition: Unit.h:263
@ UNIT_MOD_STAT_STAMINA
Definition: Unit.h:264

◆ GetTarget()

ObjectGuid Unit::GetTarget ( ) const
inline
@ UNIT_FIELD_TARGET
Definition: UpdateFields.h:92

◆ GetThreatMgr() [1/2]

ThreatMgr & Unit::GetThreatMgr ( )
inline
2142{ return m_ThreatMgr; }

◆ GetThreatMgr() [2/2]

ThreatMgr const & Unit::GetThreatMgr ( ) const
inline
2143{ return m_ThreatMgr; }

◆ GetTotalAttackPowerValue()

float Unit::GetTotalAttackPowerValue ( WeaponAttackType  attType,
Unit pVictim = nullptr 
) const
15286{
15287 if (attType == RANGED_ATTACK)
15288 {
15290 if( victim )
15291 ap += victim->GetTotalAuraModifier(SPELL_AURA_RANGED_ATTACK_POWER_ATTACKER_BONUS);
15292
15293 if (ap < 0)
15294 return 0.0f;
15296 }
15297 else
15298 {
15300 if( victim )
15301 ap += victim->GetTotalAuraModifier(SPELL_AURA_MELEE_ATTACK_POWER_ATTACKER_BONUS);
15302
15303 if (ap < 0)
15304 return 0.0f;
15306 }
15307}
@ SPELL_AURA_RANGED_ATTACK_POWER_ATTACKER_BONUS
Definition: SpellAuraDefines.h:190
@ SPELL_AURA_MELEE_ATTACK_POWER_ATTACKER_BONUS
Definition: SpellAuraDefines.h:228
@ UNIT_FIELD_ATTACK_POWER_MODS
Definition: UpdateFields.h:163
@ UNIT_FIELD_RANGED_ATTACK_POWER
Definition: UpdateFields.h:165
@ UNIT_FIELD_RANGED_ATTACK_POWER_MULTIPLIER
Definition: UpdateFields.h:167
@ UNIT_FIELD_ATTACK_POWER_MULTIPLIER
Definition: UpdateFields.h:164
@ UNIT_FIELD_ATTACK_POWER
Definition: UpdateFields.h:162
@ UNIT_FIELD_RANGED_ATTACK_POWER_MODS
Definition: UpdateFields.h:166
int32 GetInt32Value(uint16 index) const
Definition: Object.cpp:299

◆ GetTotalAuraModifier()

int32 Unit::GetTotalAuraModifier ( AuraType  auratype) const
5811{
5812 AuraEffectList const& mTotalAuraList = GetAuraEffectsByType(auratype);
5813 if (mTotalAuraList.empty())
5814 return 0;
5815
5816 int32 modifier = 0;
5817
5818 for (AuraEffectList::const_iterator i = mTotalAuraList.begin(); i != mTotalAuraList.end(); ++i)
5819 modifier += (*i)->GetAmount();
5820
5821 return modifier;
5822}

◆ GetTotalAuraModifierAreaExclusive()

int32 Unit::GetTotalAuraModifierAreaExclusive ( AuraType  auratype) const
5791{
5792 int32 modifier = 0;
5793 int32 areaModifier = 0;
5794
5795 AuraEffectList const& mTotalAuraList = GetAuraEffectsByType(auratype);
5796 for (AuraEffectList::const_iterator i = mTotalAuraList.begin(); i != mTotalAuraList.end(); ++i)
5797 {
5798 if ((*i)->GetSpellInfo()->HasAreaAuraEffect())
5799 {
5800 if (areaModifier < (*i)->GetAmount())
5801 areaModifier = (*i)->GetAmount();
5802 }
5803 else
5804 modifier += (*i)->GetAmount();
5805 }
5806
5807 return modifier + areaModifier;
5808}

◆ GetTotalAuraModifierByAffectMask()

int32 Unit::GetTotalAuraModifierByAffectMask ( AuraType  auratype,
SpellInfo const *  affectedSpell 
) const
5967{
5968 int32 modifier = 0;
5969
5970 AuraEffectList const& mTotalAuraList = GetAuraEffectsByType(auratype);
5971 for (AuraEffectList::const_iterator i = mTotalAuraList.begin(); i != mTotalAuraList.end(); ++i)
5972 if ((*i)->IsAffectedOnSpell(affectedSpell))
5973 modifier += (*i)->GetAmount();
5974
5975 return modifier;
5976}

◆ GetTotalAuraModifierByMiscMask()

int32 Unit::GetTotalAuraModifierByMiscMask ( AuraType  auratype,
uint32  misc_mask 
) const
5862{
5863 int32 modifier = 0;
5864
5865 AuraEffectList const& mTotalAuraList = GetAuraEffectsByType(auratype);
5866 for (AuraEffectList::const_iterator i = mTotalAuraList.begin(); i != mTotalAuraList.end(); ++i)
5867 {
5868 if ((*i)->GetMiscValue()& misc_mask)
5869 modifier += (*i)->GetAmount();
5870 }
5871 return modifier;
5872}

◆ GetTotalAuraModifierByMiscValue()

int32 Unit::GetTotalAuraModifierByMiscValue ( AuraType  auratype,
int32  misc_value 
) const
5915{
5916 int32 modifier = 0;
5917
5918 AuraEffectList const& mTotalAuraList = GetAuraEffectsByType(auratype);
5919 for (AuraEffectList::const_iterator i = mTotalAuraList.begin(); i != mTotalAuraList.end(); ++i)
5920 if ((*i)->GetMiscValue() == misc_value)
5921 modifier += (*i)->GetAmount();
5922
5923 return modifier;
5924}

◆ GetTotalAuraModValue()

float Unit::GetTotalAuraModValue ( UnitMods  unitMod) const
15176{
15177 if (unitMod >= UNIT_MOD_END)
15178 {
15179 LOG_ERROR("entities.unit", "attempt to access non-existing UnitMods in GetTotalAuraModValue()!");
15180 return 0.0f;
15181 }
15182
15183 if (m_auraModifiersGroup[unitMod][TOTAL_PCT] <= 0.0f)
15184 return 0.0f;
15185
15186 float value = m_auraModifiersGroup[unitMod][BASE_VALUE];
15187 value *= m_auraModifiersGroup[unitMod][BASE_PCT];
15188 value += m_auraModifiersGroup[unitMod][TOTAL_VALUE];
15189 value *= m_auraModifiersGroup[unitMod][TOTAL_PCT];
15190
15191 return value;
15192}

◆ GetTotalAuraMultiplier()

float Unit::GetTotalAuraMultiplier ( AuraType  auratype) const
5825{
5826 float multiplier = 1.0f;
5827
5828 AuraEffectList const& mTotalAuraList = GetAuraEffectsByType(auratype);
5829 for (AuraEffectList::const_iterator i = mTotalAuraList.begin(); i != mTotalAuraList.end(); ++i)
5830 AddPct(multiplier, (*i)->GetAmount());
5831
5832 return multiplier;
5833}

◆ GetTotalAuraMultiplierByAffectMask()

float Unit::GetTotalAuraMultiplierByAffectMask ( AuraType  auratype,
SpellInfo const *  affectedSpell 
) const
5979{
5980 float multiplier = 1.0f;
5981
5982 AuraEffectList const& mTotalAuraList = GetAuraEffectsByType(auratype);
5983 for (AuraEffectList::const_iterator i = mTotalAuraList.begin(); i != mTotalAuraList.end(); ++i)
5984 if ((*i)->IsAffectedOnSpell(affectedSpell))
5985 AddPct(multiplier, (*i)->GetAmount());
5986
5987 return multiplier;
5988}

◆ GetTotalAuraMultiplierByMiscMask()

float Unit::GetTotalAuraMultiplierByMiscMask ( AuraType  auratype,
uint32  misc_mask 
) const
5875{
5876 float multiplier = 1.0f;
5877
5878 AuraEffectList const& mTotalAuraList = GetAuraEffectsByType(auratype);
5879 for (AuraEffectList::const_iterator i = mTotalAuraList.begin(); i != mTotalAuraList.end(); ++i)
5880 if (((*i)->GetMiscValue() & misc_mask))
5881 AddPct(multiplier, (*i)->GetAmount());
5882
5883 return multiplier;
5884}

◆ GetTotalAuraMultiplierByMiscValue()

float Unit::GetTotalAuraMultiplierByMiscValue ( AuraType  auratype,
int32  misc_value 
) const
5927{
5928 float multiplier = 1.0f;
5929
5930 AuraEffectList const& mTotalAuraList = GetAuraEffectsByType(auratype);
5931 for (AuraEffectList::const_iterator i = mTotalAuraList.begin(); i != mTotalAuraList.end(); ++i)
5932 if ((*i)->GetMiscValue() == misc_value)
5933 AddPct(multiplier, (*i)->GetAmount());
5934
5935 return multiplier;
5936}

◆ GetTotalStatValue()

float Unit::GetTotalStatValue ( Stats  stat,
float  additionalValue = 0.0f 
) const
15160{
15161 UnitMods unitMod = UnitMods(static_cast<uint16>(UNIT_MOD_STAT_START) + stat);
15162
15163 if (m_auraModifiersGroup[unitMod][TOTAL_PCT] <= 0.0f)
15164 return 0.0f;
15165
15166 // value = ((base_value * base_pct) + total_value) * total_pct
15167 float value = m_auraModifiersGroup[unitMod][BASE_VALUE] + GetCreateStat(stat);
15168 value *= m_auraModifiersGroup[unitMod][BASE_PCT];
15169 value += m_auraModifiersGroup[unitMod][TOTAL_VALUE] + additionalValue;
15170 value *= m_auraModifiersGroup[unitMod][TOTAL_PCT];
15171
15172 return value;
15173}
UnitMods
Definition: Unit.h:261
@ UNIT_MOD_STAT_START
Definition: Unit.h:289
float GetCreateStat(Stats stat) const
Definition: Unit.h:2042

◆ getTransForm()

uint32 Unit::getTransForm ( ) const
inline
2169{ return m_transform;}

◆ GetTransGUID()

ObjectGuid Unit::GetTransGUID ( ) const
overridevirtual

Reimplemented from WorldObject.

18789{
18790 if (GetVehicle())
18791 return GetVehicleBase()->GetGUID();
18792
18793 if (GetTransport())
18794 return GetTransport()->GetGUID();
18795
18796 return ObjectGuid::Empty;
18797}

◆ GetUnitBlockChance()

float Unit::GetUnitBlockChance ( ) const
3644{
3645 if (Player const* player = ToPlayer())
3646 {
3647 if (player->CanBlock())
3648 {
3649 Item* tmpitem = player->GetUseableItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_OFFHAND);
3650 if (tmpitem && !tmpitem->IsBroken() && tmpitem->GetTemplate()->Block)
3652 }
3653 // is player but has no block ability or no not broken shield equipped
3654 return 0.0f;
3655 }
3656 else
3657 {
3658 if (ToCreature()->IsTotem())
3659 return 0.0f;
3660 else
3661 {
3662 float block = 5.0f;
3664 return block > 0.0f ? block : 0.0f;
3665 }
3666 }
3667}
@ EQUIPMENT_SLOT_OFFHAND
Definition: Player.h:692
#define INVENTORY_SLOT_BAG_0
Definition: Player.h:671
@ SPELL_AURA_MOD_BLOCK_PERCENT
Definition: SpellAuraDefines.h:114
@ PLAYER_BLOCK_PERCENTAGE
Definition: UpdateFields.h:346
ItemTemplate const * GetTemplate() const
Definition: Item.cpp:546
bool IsBroken() const
Definition: Item.h:251
uint32 Block
Definition: ItemTemplate.h:683

◆ GetUnitCriticalChance()

float Unit::GetUnitCriticalChance ( WeaponAttackType  attackType,
Unit const *  victim 
) const
3670{
3671 float crit;
3672
3673 if (GetTypeId() == TYPEID_PLAYER)
3674 {
3675 switch (attackType)
3676 {
3677 case BASE_ATTACK:
3679 break;
3680 case OFF_ATTACK:
3682 break;
3683 case RANGED_ATTACK:
3685 break;
3686 // Just for good manner
3687 default:
3688 crit = 0.0f;
3689 break;
3690 }
3691 }
3692 else
3693 {
3694 crit = 5.0f;
3697 }
3698
3699 // flat aura mods
3700 if (attackType == RANGED_ATTACK)
3701 crit += victim->GetTotalAuraModifier(SPELL_AURA_MOD_ATTACKER_RANGED_CRIT_CHANCE);
3702 else
3703 crit += victim->GetTotalAuraModifier(SPELL_AURA_MOD_ATTACKER_MELEE_CRIT_CHANCE);
3704
3705 AuraEffectList const& mTotalAuraList = victim->GetAuraEffectsByType(SPELL_AURA_MOD_CRIT_CHANCE_FOR_CASTER);
3706 for (AuraEffectList::const_iterator i = mTotalAuraList.begin(); i != mTotalAuraList.end(); ++i)
3707 {
3708 if (GetGUID() != (*i)->GetCasterGUID())
3709 continue;
3710
3711 crit += (*i)->GetAmount();
3712 }
3713
3714 // reduce crit chance from Rating for players
3715 if (attackType != RANGED_ATTACK)
3716 Unit::ApplyResilience(victim, &crit, nullptr, false, CR_CRIT_TAKEN_MELEE);
3717 else
3718 Unit::ApplyResilience(victim, &crit, nullptr, false, CR_CRIT_TAKEN_RANGED);
3719
3720 // Apply crit chance from defence skill
3721 crit += (int32(GetMaxSkillValueForLevel(victim)) - int32(victim->GetDefenseSkillValue(this))) * 0.04f;
3722
3723 // xinef: SPELL_AURA_MOD_ATTACKER_SPELL_AND_WEAPON_CRIT_CHANCE should be calculated at the end
3724 crit += victim->GetTotalAuraModifier(SPELL_AURA_MOD_ATTACKER_SPELL_AND_WEAPON_CRIT_CHANCE);
3725
3726 if (crit < 0.0f)
3727 crit = 0.0f;
3728 return crit;
3729}
@ SPELL_AURA_MOD_CRIT_CHANCE_FOR_CASTER
Definition: SpellAuraDefines.h:371
@ SPELL_AURA_MOD_ATTACKER_RANGED_CRIT_CHANCE
Definition: SpellAuraDefines.h:251
@ SPELL_AURA_MOD_ATTACKER_SPELL_AND_WEAPON_CRIT_CHANCE
Definition: SpellAuraDefines.h:260
@ SPELL_AURA_MOD_ATTACKER_MELEE_CRIT_CHANCE
Definition: SpellAuraDefines.h:250
@ SPELL_AURA_MOD_CRIT_PCT
Definition: SpellAuraDefines.h:353
@ SPELL_AURA_MOD_WEAPON_CRIT_PERCENT
Definition: SpellAuraDefines.h:115
@ PLAYER_RANGED_CRIT_PERCENTAGE
Definition: UpdateFields.h:352
@ PLAYER_CRIT_PERCENTAGE
Definition: UpdateFields.h:351
@ PLAYER_OFFHAND_CRIT_PERCENTAGE
Definition: UpdateFields.h:353
uint16 GetMaxSkillValueForLevel(Unit const *target=nullptr) const
Definition: Unit.h:1545

◆ GetUnitDodgeChance()

float Unit::GetUnitDodgeChance ( ) const
3582{
3583 if (GetTypeId() == TYPEID_PLAYER)
3584 return ToPlayer()->GetRealDodge(); //GetFloatValue(PLAYER_DODGE_PERCENTAGE);
3585 else
3586 {
3587 if (ToCreature()->IsTotem())
3588 return 0.0f;
3589 else
3590 {
3591 float dodge = ToCreature()->isWorldBoss() ? 5.85f : 5.0f; // Xinef: bosses should have 6.5% dodge (5.9 + 0.6 from defense skill difference)
3593 return dodge > 0.0f ? dodge : 0.0f;
3594 }
3595 }
3596}
@ SPELL_AURA_MOD_DODGE_PERCENT
Definition: SpellAuraDefines.h:112
float GetRealDodge() const
Definition: Player.h:2553

◆ GetUnitFlags()

UnitFlags Unit::GetUnitFlags ( ) const
inline
UnitFlags
Definition: Unit.h:446

◆ GetUnitFlags2()

UnitFlags2 Unit::GetUnitFlags2 ( ) const
inline
UnitFlags2
Definition: Unit.h:486
@ UNIT_FIELD_FLAGS_2
Definition: UpdateFields.h:118

◆ GetUnitMeleeSkill()

uint32 Unit::GetUnitMeleeSkill ( Unit const *  target = nullptr) const
inline
1633{ return (target ? getLevelForTarget(target) : getLevel()) * 5; }

◆ GetUnitMissChance()

float Unit::GetUnitMissChance ( WeaponAttackType  attType) const
3629{
3630 float miss_chance = 5.00f;
3631
3632 if (Player const* player = ToPlayer())
3633 miss_chance += player->GetMissPercentageFromDefence();
3634
3635 if (attType == RANGED_ATTACK)
3637 else
3639
3640 return miss_chance;
3641}
@ SPELL_AURA_MOD_ATTACKER_MELEE_HIT_CHANCE
Definition: SpellAuraDefines.h:247
@ SPELL_AURA_MOD_ATTACKER_RANGED_HIT_CHANCE
Definition: SpellAuraDefines.h:248

◆ GetUnitMovementFlags()

uint32 Unit::GetUnitMovementFlags ( ) const
inline
2270{ return m_movementInfo.flags; }

◆ GetUnitParryChance()

float Unit::GetUnitParryChance ( ) const
3599{
3600 float chance = 0.0f;
3601
3602 if (Player const* player = ToPlayer())
3603 {
3604 if (player->CanParry())
3605 {
3606 Item* tmpitem = player->GetWeaponForAttack(BASE_ATTACK, true);
3607 if (!tmpitem)
3608 tmpitem = player->GetWeaponForAttack(OFF_ATTACK, true);
3609
3610 if (tmpitem)
3611 chance = player->GetRealParry(); //GetFloatValue(PLAYER_PARRY_PERCENTAGE);
3612 }
3613 }
3614 else if (GetTypeId() == TYPEID_UNIT)
3615 {
3616 if (ToCreature()->isWorldBoss())
3617 chance = 13.4f; // + 0.6 by skill diff
3619 chance = 5.0f;
3620
3621 // Xinef: if aura is present, type should not matter
3623 }
3624
3625 return chance > 0.0f ? chance : 0.0f;
3626}
@ SPELL_AURA_MOD_PARRY_PERCENT
Definition: SpellAuraDefines.h:110

◆ GetUnitState()

uint32 Unit::GetUnitState ( ) const
inline
1400{ return m_state; }

◆ GetUnitTypeMask()

uint32 Unit::GetUnitTypeMask ( ) const
inline
1409{ return m_unitTypeMask; }

◆ GetVehicle()

Vehicle * Unit::GetVehicle ( ) const
inline
2349{ return m_vehicle; }

◆ GetVehicleBase()

Unit * Unit::GetVehicleBase ( ) const
18775{
18776 return m_vehicle ? m_vehicle->GetBase() : nullptr;
18777}

◆ GetVehicleCreatureBase()

Creature * Unit::GetVehicleCreatureBase ( ) const
18780{
18781 if (Unit* veh = GetVehicleBase())
18782 if (Creature* c = veh->ToCreature())
18783 return c;
18784
18785 return nullptr;
18786}

◆ GetVehicleKit()

Vehicle * Unit::GetVehicleKit ( ) const
inline
2348{ return m_vehicleKit; }

◆ GetVictim()

Unit * Unit::GetVictim ( ) const
inline
1386{ return m_attacking; }

◆ GetVisibleAura()

AuraApplication * Unit::GetVisibleAura ( uint8  slot)
inline
2150 {
2151 VisibleAuraMap::iterator itr = m_visibleAuras.find(slot);
2152 if (itr != m_visibleAuras.end())
2153 return itr->second;
2154 return nullptr;
2155 }

◆ GetVisibleAuras()

VisibleAuraMap const * Unit::GetVisibleAuras ( )
inline
2148{ return &m_visibleAuras; }

◆ GetWeaponDamageRange()

float Unit::GetWeaponDamageRange ( WeaponAttackType  attType,
WeaponDamageRange  type,
uint8  damageIndex = 0 
) const
15310{
15311 if (attType == OFF_ATTACK && !haveOffhandWeapon())
15312 return 0.0f;
15313
15314 return m_weaponDamage[attType][type][damageIndex];
15315}

◆ GetWeaponProcChance()

float Unit::GetWeaponProcChance ( ) const
13345{
13346 // normalized proc chance for weapon attack speed
13347 // (odd formula...)
13349 return (GetAttackTime(BASE_ATTACK) * 1.8f / 1000.0f);
13351 return (GetAttackTime(OFF_ATTACK) * 1.6f / 1000.0f);
13352 return 0;
13353}

◆ GetWeaponSkillValue()

uint32 Unit::GetWeaponSkillValue ( WeaponAttackType  attType,
Unit const *  target = nullptr 
) const
3732{
3733 uint32 value = 0;
3734 if (Player const* player = ToPlayer())
3735 {
3736 Item* item = player->GetWeaponForAttack(attType, true);
3737
3738 // feral or unarmed skill only for base attack
3739 if (attType != BASE_ATTACK && !item)
3740 return 0;
3741
3742 if (IsInFeralForm())
3743 return GetMaxSkillValueForLevel(); // always maximized SKILL_FERAL_COMBAT in fact
3744
3745 // weapon skill or (unarmed for base attack)
3746 uint32 skill = SKILL_UNARMED;
3747 if (item)
3748 skill = item->GetSkill();
3749
3750 // in PvP use full skill instead current skill value
3751 value = (target && target->IsControlledByPlayer())
3752 ? player->GetMaxSkillValue(skill)
3753 : player->GetSkillValue(skill);
3754 // Modify value from ratings
3755 value += uint32(player->GetRatingBonusValue(CR_WEAPON_SKILL));
3756 switch (attType)
3757 {
3758 case BASE_ATTACK:
3759 value += uint32(player->GetRatingBonusValue(CR_WEAPON_SKILL_MAINHAND));
3760 break;
3761 case OFF_ATTACK:
3762 value += uint32(player->GetRatingBonusValue(CR_WEAPON_SKILL_OFFHAND));
3763 break;
3764 case RANGED_ATTACK:
3765 value += uint32(player->GetRatingBonusValue(CR_WEAPON_SKILL_RANGED));
3766 break;
3767 default:
3768 break;
3769 }
3770 }
3771 else
3772 value = GetUnitMeleeSkill(target);
3773 return value;
3774}
@ SKILL_UNARMED
Definition: SharedDefines.h:2879
@ CR_WEAPON_SKILL_RANGED
Definition: Unit.h:426
@ CR_WEAPON_SKILL
Definition: Unit.h:404
@ CR_WEAPON_SKILL_OFFHAND
Definition: Unit.h:425
@ CR_WEAPON_SKILL_MAINHAND
Definition: Unit.h:424
uint32 GetSkill()
Definition: Item.cpp:557
bool IsInFeralForm() const
Definition: Unit.h:2074

◆ HandleAuraProc()

bool Unit::HandleAuraProc ( Unit victim,
uint32  damage,
Aura triggeredByAura,
SpellInfo const *  procSpell,
uint32  procFlag,
uint32  procEx,
uint32  cooldown,
bool *  handled 
)
private
8679{
8680 SpellInfo const* dummySpell = triggeredByAura->GetSpellInfo();
8681
8682 switch (dummySpell->SpellFamilyName)
8683 {
8685 switch (dummySpell->Id)
8686 {
8687 // Nevermelting Ice Crystal
8688 case 71564:
8689 RemoveAuraFromStack(71564);
8690 *handled = true;
8691 break;
8692 // Gaseous Bloat
8693 case 70672:
8694 case 72455:
8695 case 72832:
8696 case 72833:
8697 {
8698 if (Unit* caster = triggeredByAura->GetCaster())
8699 if (victim && caster->GetGUID() == victim->GetGUID())
8700 {
8701 *handled = true;
8702 uint32 stack = triggeredByAura->GetStackAmount();
8703 int32 const mod = (GetMap()->GetSpawnMode() & 1) ? 1500 : 1250;
8704 int32 dmg = 0;
8705 for (uint8 i = 1; i <= stack; ++i)
8706 dmg += mod * i;
8707 caster->CastCustomSpell(70701, SPELLVALUE_BASE_POINT0, dmg);
8708 }
8709 break;
8710 }
8711 // Ball of Flames Proc
8712 case 71756:
8713 case 72782:
8714 case 72783:
8715 case 72784:
8716 RemoveAuraFromStack(dummySpell->Id);
8717 *handled = true;
8718 break;
8719 // Discerning Eye of the Beast
8720 case 59915:
8721 {
8722 CastSpell(this, 59914, true); // 59914 already has correct basepoints in DBC, no need for custom bp
8723 *handled = true;
8724 break;
8725 }
8726 // Swift Hand of Justice
8727 case 59906:
8728 {
8729 int32 bp0 = CalculatePct(GetMaxHealth(), dummySpell->Effects[EFFECT_0]. CalcValue());
8730 CastCustomSpell(this, 59913, &bp0, nullptr, nullptr, true);
8731 *handled = true;
8732 break;
8733 }
8734 }
8735
8736 break;
8737 case SPELLFAMILY_MAGE:
8738 {
8739 // Combustion
8740 switch (dummySpell->Id)
8741 {
8742 case 11129:
8743 {
8744 *handled = true;
8745 Unit* caster = triggeredByAura->GetCaster();
8746 if (!caster || !damage)
8747 return false;
8748
8749 // last charge and crit
8750 if (triggeredByAura->GetCharges() <= 1 && (procEx & PROC_EX_CRITICAL_HIT))
8751 return true; // charge counting (will removed)
8752
8753 CastSpell(this, 28682, true);
8754
8755 return procEx & PROC_EX_CRITICAL_HIT;
8756 }
8757 // Empowered Fire
8758 case 31656:
8759 case 31657:
8760 case 31658:
8761 {
8762 *handled = true;
8763
8764 SpellInfo const* spInfo = sSpellMgr->GetSpellInfo(67545);
8765 if (!spInfo)
8766 return false;
8767
8768 int32 bp0 = int32(CalculatePct(GetMaxPower(POWER_MANA), spInfo->Effects[0].CalcValue()));
8769 CastCustomSpell(this, 67545, &bp0, nullptr, nullptr, true, nullptr, triggeredByAura->GetEffect(EFFECT_0), GetGUID());
8770 return true;
8771 }
8772 }
8773 break;
8774 }
8776 {
8777 // Blood of the North
8778 // Reaping
8779 // Death Rune Mastery
8780 // xinef: Icon 22 is used for item bonus, skip
8781 if (dummySpell->SpellIconID == 3041 || (dummySpell->SpellIconID == 22 && dummySpell->Id != 62459) || dummySpell->SpellIconID == 2622)
8782 {
8783 *handled = true;
8784 // Convert recently used Blood Rune to Death Rune
8785 if (Player* player = ToPlayer())
8786 {
8787 if (player->getClass() != CLASS_DEATH_KNIGHT)
8788 return false;
8789
8790 // xinef: not true
8791 //RuneType rune = ToPlayer()->GetLastUsedRune();
8792 // can't proc from death rune use
8793 //if (rune == RUNE_DEATH)
8794 // return false;
8795 AuraEffect* aurEff = triggeredByAura->GetEffect(EFFECT_0);
8796 if (!aurEff)
8797 return false;
8798
8799 // Reset amplitude - set death rune remove timer to 30s
8800 aurEff->ResetPeriodic(true);
8801 uint32 runesLeft;
8802
8803 if (dummySpell->SpellIconID == 2622)
8804 runesLeft = 2;
8805 else
8806 runesLeft = 1;
8807
8808 for (uint8 i = 0; i < MAX_RUNES && runesLeft; ++i)
8809 {
8810 if (dummySpell->SpellIconID == 2622)
8811 {
8812 if (player->GetCurrentRune(i) == RUNE_DEATH ||
8813 player->GetBaseRune(i) == RUNE_BLOOD)
8814 continue;
8815 }
8816 else
8817 {
8818 if (player->GetCurrentRune(i) == RUNE_DEATH ||
8819 player->GetBaseRune(i) != RUNE_BLOOD)
8820 continue;
8821 }
8822 if (player->GetRuneCooldown(i) != player->GetRuneBaseCooldown(i, false))
8823 continue;
8824
8825 --runesLeft;
8826 // Mark aura as used
8827 player->AddRuneByAuraEffect(i, RUNE_DEATH, aurEff);
8828 }
8829 return true;
8830 }
8831 return false;
8832 }
8833 break;
8834 }
8836 {
8837 switch (dummySpell->Id)
8838 {
8839 // Item - Warrior T10 Protection 4P Bonus
8840 case 70844:
8841 {
8842 int32 basepoints0 = CalculatePct(GetMaxHealth(), dummySpell->Effects[EFFECT_1]. CalcValue());
8843 CastCustomSpell(this, 70845, &basepoints0, nullptr, nullptr, true);
8844 break;
8845 }
8846 default:
8847 break;
8848 }
8849 break;
8850 }
8851 case SPELLFAMILY_SHAMAN:
8852 {
8853 // Flurry
8854 if ((dummySpell->SpellFamilyFlags[1] & 0x00000200) != 0)
8855 {
8856 if (cooldown)
8857 {
8858 if (HasSpellCooldown(dummySpell->Id))
8859 {
8860 *handled = true;
8861 break;
8862 }
8863
8864 AddSpellCooldown(dummySpell->Id, 0, cooldown);
8865 }
8866 }
8867 break;
8868 }
8869 }
8870 return false;
8871}
@ RUNE_DEATH
Definition: Player.h:413
@ RUNE_BLOOD
Definition: Player.h:410
@ EFFECT_1
Definition: SharedDefines.h:31
@ EFFECT_0
Definition: SharedDefines.h:30
@ SPELLFAMILY_MAGE
Definition: SharedDefines.h:3503
@ SPELLFAMILY_GENERIC
Definition: SharedDefines.h:3500
@ SPELLFAMILY_WARRIOR
Definition: SharedDefines.h:3504
@ SPELLFAMILY_SHAMAN
Definition: SharedDefines.h:3511
@ SPELLFAMILY_DEATHKNIGHT
Definition: SharedDefines.h:3515
void ResetPeriodic(bool resetPeriodicTimer=false)
Definition: SpellAuraEffects.h:88
AuraEffect * GetEffect(uint8 effIndex) const
Definition: SpellAuras.h:175
uint8 GetSpawnMode() const
Definition: Map.h:419
virtual bool HasSpellCooldown(uint32) const
Definition: Unit.h:2413
virtual void AddSpellCooldown(uint32, uint32, uint32, bool needSendToClient=false, bool forceSendToSpectator=false)
Definition: Unit.h:2415
void RemoveAuraFromStack(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT)
Definition: Unit.cpp:4839

◆ HandleAuraRaidProcFromCharge()

bool Unit::HandleAuraRaidProcFromCharge ( AuraEffect triggeredByAura)
private
17702{
17703 // aura can be deleted at casts
17704 SpellInfo const* spellProto = triggeredByAura->GetSpellInfo();
17705
17706 uint32 damageSpellId;
17707 switch (spellProto->Id)
17708 {
17709 case 57949: // shiver
17710 damageSpellId = 57952;
17711 //animationSpellId = 57951; dummy effects for jump spell have unknown use (see also 41637)
17712 break;
17713 case 59978: // shiver
17714 damageSpellId = 59979;
17715 break;
17716 case 43593: // Cold Stare
17717 damageSpellId = 43594;
17718 break;
17719 default:
17720 LOG_ERROR("entities.unit", "Unit::HandleAuraRaidProcFromCharge, received unhandled spell: {}", spellProto->Id);
17721 return false;
17722 }
17723
17724 ObjectGuid caster_guid = triggeredByAura->GetCasterGUID();
17725
17726 // jumps
17727 int32 jumps = triggeredByAura->GetBase()->GetCharges() - 1;
17728
17729 // current aura expire
17730 triggeredByAura->GetBase()->SetCharges(1); // will removed at next charges decrease
17731
17732 // next target selection
17733 if (jumps > 0)
17734 {
17735 if (Unit* caster = triggeredByAura->GetCaster())
17736 {
17737 float radius = triggeredByAura->GetSpellInfo()->Effects[triggeredByAura->GetEffIndex()].CalcRadius(caster);
17738 if (Unit* target = GetNextRandomRaidMemberOrPet(radius))
17739 {
17740 CastSpell(target, spellProto, true, nullptr, triggeredByAura, caster_guid);
17741 if (Aura* aura = target->GetAura(spellProto->Id, caster->GetGUID()))
17742 aura->SetCharges(jumps);
17743 }
17744 }
17745 }
17746
17747 CastSpell(this, damageSpellId, true, nullptr, triggeredByAura, caster_guid);
17748
17749 return true;
17750}
void SetCharges(uint8 charges)
Definition: SpellAuras.cpp:966
Unit * GetNextRandomRaidMemberOrPet(float radius)
Definition: Unit.cpp:11062

◆ HandleAuraRaidProcFromChargeWithValue()

bool Unit::HandleAuraRaidProcFromChargeWithValue ( AuraEffect triggeredByAura)
private
17613{
17614 // aura can be deleted at casts
17615 SpellInfo const* spellProto = triggeredByAura->GetSpellInfo();
17616 int32 heal = triggeredByAura->GetAmount();
17617 ObjectGuid caster_guid = triggeredByAura->GetCasterGUID();
17618
17619 // Currently only Prayer of Mending
17620 if (!(spellProto->SpellFamilyName == SPELLFAMILY_PRIEST && spellProto->SpellFamilyFlags[1] & 0x20))
17621 {
17622 LOG_DEBUG("spells.aura", "Unit::HandleAuraRaidProcFromChargeWithValue, received not handled spell: {}", spellProto->Id);
17623 return false;
17624 }
17625
17626 // jumps
17627 int32 jumps = triggeredByAura->GetBase()->GetCharges() - 1;
17628
17629 // current aura expire
17630 triggeredByAura->GetBase()->SetCharges(1); // will removed at next charges decrease
17631
17632 // next target selection
17633 if (jumps > 0)
17634 {
17635 if (Unit* caster = triggeredByAura->GetCaster())
17636 {
17637 // smart healing
17638 float radius = triggeredByAura->GetSpellInfo()->Effects[triggeredByAura->GetEffIndex()].CalcRadius(caster);
17639 std::list<Unit*> nearMembers;
17640
17641 Player* player = nullptr;
17642 if (GetTypeId() == TYPEID_PLAYER)
17643 player = ToPlayer();
17644 else if (GetOwner())
17645 player = GetOwner()->ToPlayer();
17646
17647 if (player)
17648 {
17649 Group* group = player->GetGroup();
17650 if (!group)
17651 {
17652 if (player != this)
17653 {
17654 if (IsWithinDistInMap(player, radius))
17655 nearMembers.push_back(player);
17656 }
17657 else if (Unit* pet = GetGuardianPet())
17658 {
17659 if (IsWithinDistInMap(pet, radius))
17660 nearMembers.push_back(pet);
17661 }
17662 }
17663 else
17664 {
17665 for (GroupReference* itr = group->GetFirstMember(); itr != nullptr; itr = itr->next())
17666 if (Player* Target = itr->GetSource())
17667 {
17668 if (Target != this && !IsWithinDistInMap(Target, radius))
17669 continue;
17670
17671 // IsHostileTo check duel and controlled by enemy
17672 if (Target != this && Target->IsAlive() && !IsHostileTo(Target))
17673 nearMembers.push_back(Target);
17674
17675 // Push player's pet to vector
17676 if (Unit* pet = Target->GetGuardianPet())
17677 if (pet != this && pet->IsAlive() && IsWithinDistInMap(pet, radius) && !IsHostileTo(pet))
17678 nearMembers.push_back(pet);
17679 }
17680 }
17681
17682 if (!nearMembers.empty())
17683 {
17684 nearMembers.sort(Acore::HealthPctOrderPred());
17685 if (Unit* target = nearMembers.front())
17686 {
17687 CastSpell(target, 41637 /*Dummy visual effect triggered by main spell cast*/, true);
17688 CastCustomSpell(target, spellProto->Id, &heal, nullptr, nullptr, true, nullptr, triggeredByAura, caster_guid);
17689 if (Aura* aura = target->GetAura(spellProto->Id, caster->GetGUID()))
17690 aura->SetCharges(jumps);
17691 }
17692 }
17693 }
17694 }
17695 }
17696
17697 // heal
17698 CastCustomSpell(this, 33110, &heal, nullptr, nullptr, true, nullptr, nullptr, caster_guid);
17699 return true;
17700}
@ SPELLFAMILY_PRIEST
Definition: SharedDefines.h:3506
Definition: Unit.h:2625

◆ HandleDummyAuraProc()

bool Unit::HandleDummyAuraProc ( Unit victim,
uint32  damage,
AuraEffect triggeredByAura,
SpellInfo const *  procSpell,
uint32  procFlag,
uint32  procEx,
uint32  cooldown,
Spell const *  spellProc = nullptr 
)
private
6490{
6491 SpellInfo const* dummySpell = triggeredByAura->GetSpellInfo();
6492 uint32 effIndex = triggeredByAura->GetEffIndex();
6493 int32 triggerAmount = triggeredByAura->GetAmount();
6494
6495 Item* castItem = triggeredByAura->GetBase()->GetCastItemGUID() && GetTypeId() == TYPEID_PLAYER
6496 ? ToPlayer()->GetItemByGuid(triggeredByAura->GetBase()->GetCastItemGUID()) : nullptr;
6497
6498 uint32 triggered_spell_id = 0;
6499 uint32 cooldown_spell_id = 0; // for random trigger, will be one of the triggered spell to avoid repeatable triggers
6500 // otherwise, it's the triggered_spell_id by default
6501 Unit* target = victim;
6502 int32 basepoints0 = 0;
6503 ObjectGuid originalCaster;
6504
6505 switch (dummySpell->SpellFamilyName)
6506 {
6508 {
6509 switch (dummySpell->Id)
6510 {
6511 // Overkill
6512 case 58426:
6513 {
6514 triggered_spell_id = 58427;
6515 break;
6516 }
6517 // Unstable Power
6518 case 24658:
6519 {
6520 if (!procSpell || procSpell->Id == 24659)
6521 return false;
6522 // Need remove one 24659 aura
6523 RemoveAuraFromStack(24659);
6524 return true;
6525 }
6526 // Restless Strength
6527 case 24661:
6528 {
6529 // Need remove one 24662 aura
6530 RemoveAuraFromStack(24662);
6531 return true;
6532 }
6533 // Mark of Malice
6534 case 33493:
6535 {
6536 if (triggeredByAura->GetBase()->GetCharges() > 1)
6537 return true;
6538
6539 target = this;
6540 triggered_spell_id = 33494;
6541 break;
6542 }
6543 // Twisted Reflection (boss spell)
6544 case 21063:
6545 triggered_spell_id = 21064;
6546 break;
6547 // Vampiric Aura (boss spell)
6548 case 38196:
6549 {
6550 basepoints0 = 3 * damage; // 300%
6551 if (basepoints0 < 0)
6552 return false;
6553
6554 triggered_spell_id = 31285;
6555 target = this;
6556 break;
6557 }
6558 // Aura of Madness (Darkmoon Card: Madness trinket)
6559 //=====================================================
6560 // 39511 Sociopath: +35 strength (Paladin, Rogue, Druid, Warrior)
6561 // 40997 Delusional: +70 attack power (Rogue, Hunter, Paladin, Warrior, Druid)
6562 // 40998 Kleptomania: +35 agility (Warrior, Rogue, Paladin, Hunter, Druid)
6563 // 40999 Megalomania: +41 damage/healing (Druid, Shaman, Priest, Warlock, Mage, Paladin)
6564 // 41002 Paranoia: +35 spell/melee/ranged crit strike rating (All classes)
6565 // 41005 Manic: +35 haste (spell, melee and ranged) (All classes)
6566 // 41009 Narcissism: +35 intellect (Druid, Shaman, Priest, Warlock, Mage, Paladin, Hunter)
6567 // 41011 Martyr Complex: +35 stamina (All classes)
6568 // 41406 Dementia: Every 5 seconds either gives you +5% damage/healing. (Druid, Shaman, Priest, Warlock, Mage, Paladin)
6569 // 41409 Dementia: Every 5 seconds either gives you -5% damage/healing. (Druid, Shaman, Priest, Warlock, Mage, Paladin)
6570 case 39446:
6571 {
6572 if (GetTypeId() != TYPEID_PLAYER || !IsAlive())
6573 return false;
6574
6575 // Select class defined buff
6576 switch (getClass())
6577 {
6578 case CLASS_PALADIN: // 39511, 40997, 40998, 40999, 41002, 41005, 41009, 41011, 41409
6579 case CLASS_DRUID: // 39511, 40997, 40998, 40999, 41002, 41005, 41009, 41011, 41409
6580 triggered_spell_id = RAND(39511, 40997, 40998, 40999, 41002, 41005, 41009, 41011, 41409);
6581 cooldown_spell_id = 39511;
6582 break;
6583 case CLASS_ROGUE: // 39511, 40997, 40998, 41002, 41005, 41011
6584 case CLASS_WARRIOR: // 39511, 40997, 40998, 41002, 41005, 41011
6585 case CLASS_DEATH_KNIGHT:
6586 triggered_spell_id = RAND(39511, 40997, 40998, 41002, 41005, 41011);
6587 cooldown_spell_id = 39511;
6588 break;
6589 case CLASS_PRIEST: // 40999, 41002, 41005, 41009, 41011, 41406, 41409
6590 case CLASS_SHAMAN: // 40999, 41002, 41005, 41009, 41011, 41406, 41409
6591 case CLASS_MAGE: // 40999, 41002, 41005, 41009, 41011, 41406, 41409
6592 case CLASS_WARLOCK: // 40999, 41002, 41005, 41009, 41011, 41406, 41409
6593 triggered_spell_id = RAND(40999, 41002, 41005, 41009, 41011, 41406, 41409);
6594 cooldown_spell_id = 40999;
6595 break;
6596 case CLASS_HUNTER: // 40997, 40999, 41002, 41005, 41009, 41011, 41406, 41409
6597 triggered_spell_id = RAND(40997, 40999, 41002, 41005, 41009, 41011, 41406, 41409);
6598 cooldown_spell_id = 40997;
6599 break;
6600 default:
6601 return false;
6602 }
6603
6604 target = this;
6605 if (roll_chance_i(10))
6606 ToPlayer()->Say("This is Madness!", LANG_UNIVERSAL); // TODO: It should be moved to database, shouldn't it?
6607 break;
6608 }
6609 // Sunwell Exalted Caster Neck (??? neck)
6610 // cast ??? Light's Wrath if Exalted by Aldor
6611 // cast ??? Arcane Bolt if Exalted by Scryers
6612 case 46569:
6613 return false; // old unused version
6614 // Sunwell Exalted Caster Neck (Shattered Sun Pendant of Acumen neck)
6615 // cast 45479 Light's Wrath if Exalted by Aldor
6616 // cast 45429 Arcane Bolt if Exalted by Scryers
6617 case 45481:
6618 {
6619 Player* player = ToPlayer();
6620 if (!player)
6621 return false;
6622
6623 // Get Aldor reputation rank
6624 if (player->GetReputationRank(932) == REP_EXALTED)
6625 {
6626 target = this;
6627 triggered_spell_id = 45479;
6628 break;
6629 }
6630 // Get Scryers reputation rank
6631 if (player->GetReputationRank(934) == REP_EXALTED)
6632 {
6633 // triggered at positive/self casts also, current attack target used then
6634 if (target && IsFriendlyTo(target))
6635 {
6636 target = GetVictim();
6637 if (!target)
6638 {
6639 target = player->GetSelectedUnit();
6640 if (!target)
6641 return false;
6642 }
6643 if (IsFriendlyTo(target))
6644 return false;
6645 }
6646
6647 triggered_spell_id = 45429;
6648 break;
6649 }
6650 return false;
6651 }
6652 // Sunwell Exalted Melee Neck (Shattered Sun Pendant of Might neck)
6653 // cast 45480 Light's Strength if Exalted by Aldor
6654 // cast 45428 Arcane Strike if Exalted by Scryers
6655 case 45482:
6656 {
6657 if (GetTypeId() != TYPEID_PLAYER)
6658 return false;
6659
6660 // Get Aldor reputation rank
6661 if (ToPlayer()->GetReputationRank(932) == REP_EXALTED)
6662 {
6663 target = this;
6664 triggered_spell_id = 45480;
6665 break;
6666 }
6667 // Get Scryers reputation rank
6668 if (ToPlayer()->GetReputationRank(934) == REP_EXALTED)
6669 {
6670 triggered_spell_id = 45428;
6671 break;
6672 }
6673 return false;
6674 }
6675 // Sunwell Exalted Tank Neck (Shattered Sun Pendant of Resolve neck)
6676 // cast 45431 Arcane Insight if Exalted by Aldor
6677 // cast 45432 Light's Ward if Exalted by Scryers
6678 case 45483:
6679 {
6680 if (GetTypeId() != TYPEID_PLAYER)
6681 return false;
6682
6683 // Get Aldor reputation rank
6684 if (ToPlayer()->GetReputationRank(932) == REP_EXALTED)
6685 {
6686 target = this;
6687 triggered_spell_id = 45432;
6688 break;
6689 }
6690 // Get Scryers reputation rank
6691 if (ToPlayer()->GetReputationRank(934) == REP_EXALTED)
6692 {
6693 target = this;
6694 triggered_spell_id = 45431;
6695 break;
6696 }
6697 return false;
6698 }
6699 // Sunwell Exalted Healer Neck (Shattered Sun Pendant of Restoration neck)
6700 // cast 45478 Light's Salvation if Exalted by Aldor
6701 // cast 45430 Arcane Surge if Exalted by Scryers
6702 case 45484:
6703 {
6704 if (GetTypeId() != TYPEID_PLAYER)
6705 return false;
6706
6707 // Get Aldor reputation rank
6708 if (ToPlayer()->GetReputationRank(932) == REP_EXALTED)
6709 {
6710 target = this;
6711 triggered_spell_id = 45478;
6712 break;
6713 }
6714 // Get Scryers reputation rank
6715 if (ToPlayer()->GetReputationRank(934) == REP_EXALTED)
6716 {
6717 triggered_spell_id = 45430;
6718 break;
6719 }
6720 return false;
6721 }
6722 // Kill command
6723 case 58914:
6724 {
6725 // Remove aura stack from pet
6726 RemoveAuraFromStack(58914);
6727 Unit* owner = GetOwner();
6728 if (!owner)
6729 return true;
6730 // reduce the owner's aura stack
6731 owner->RemoveAuraFromStack(34027);
6732 return true;
6733 }
6734 // Vampiric Touch (generic, used by some boss)
6735 case 52723:
6736 case 60501:
6737 {
6738 triggered_spell_id = 52724;
6739 basepoints0 = damage / 2;
6740 target = this;
6741 break;
6742 }
6743 // Divine purpose
6744 case 31871:
6745 case 31872:
6746 {
6747 // Roll chane
6748 if (!victim || !victim->IsAlive() || !roll_chance_i(triggerAmount))
6749 return false;
6750
6751 // Remove any stun effect on target
6753 return true;
6754 }
6755 // Glyph of Life Tap
6756 case 63320:
6757 {
6758 triggered_spell_id = 63321; // Life Tap
6759 break;
6760 }
6761 case 71519: // Deathbringer's Will Normal
6762 {
6763 if (GetTypeId() != TYPEID_PLAYER || HasSpellCooldown(71484))
6764 return false;
6765
6766 AddSpellCooldown(71484, 0, cooldown);
6767
6768 std::vector<uint32> RandomSpells;
6769 switch (getClass())
6770 {
6771 case CLASS_WARRIOR:
6772 case CLASS_PALADIN:
6773 case CLASS_DEATH_KNIGHT:
6774 RandomSpells.push_back(71484);
6775 RandomSpells.push_back(71491);
6776 RandomSpells.push_back(71492);
6777 break;
6778 case CLASS_SHAMAN:
6779 case CLASS_ROGUE:
6780 RandomSpells.push_back(71486);
6781 RandomSpells.push_back(71485);
6782 RandomSpells.push_back(71492);
6783 break;
6784 case CLASS_DRUID:
6785 RandomSpells.push_back(71484);
6786 RandomSpells.push_back(71485);
6787 RandomSpells.push_back(71492);
6788 break;
6789 case CLASS_HUNTER:
6790 RandomSpells.push_back(71486);
6791 RandomSpells.push_back(71491);
6792 RandomSpells.push_back(71485);
6793 break;
6794 default:
6795 return false;
6796 }
6797 if (RandomSpells.empty()) // shouldn't happen
6798 return false;
6799
6800 uint8 rand_spell = irand(0, (RandomSpells.size() - 1));
6801 CastSpell(target, RandomSpells[rand_spell], true, castItem, triggeredByAura, originalCaster);
6802 break;
6803 }
6804 case 71562: // Deathbringer's Will Heroic
6805 {
6806 if (GetTypeId() != TYPEID_PLAYER || HasSpellCooldown(71561))
6807 return false;
6808
6809 AddSpellCooldown(71561, 0, cooldown);
6810
6811 std::vector<uint32> RandomSpells;
6812 switch (getClass())
6813 {
6814 case CLASS_WARRIOR:
6815 case CLASS_PALADIN:
6816 case CLASS_DEATH_KNIGHT:
6817 RandomSpells.push_back(71561);
6818 RandomSpells.push_back(71559);
6819 RandomSpells.push_back(71560);
6820 break;
6821 case CLASS_SHAMAN:
6822 case CLASS_ROGUE:
6823 RandomSpells.push_back(71558);
6824 RandomSpells.push_back(71556);
6825 RandomSpells.push_back(71560);
6826 break;
6827 case CLASS_DRUID:
6828 RandomSpells.push_back(71561);
6829 RandomSpells.push_back(71556);
6830 RandomSpells.push_back(71560);
6831 break;
6832 case CLASS_HUNTER:
6833 RandomSpells.push_back(71558);
6834 RandomSpells.push_back(71559);
6835 RandomSpells.push_back(71556);
6836 break;
6837 default:
6838 return false;
6839 }
6840 if (RandomSpells.empty()) // shouldn't happen
6841 return false;
6842
6843 uint8 rand_spell = irand(0, (RandomSpells.size() - 1));
6844 CastSpell(target, RandomSpells[rand_spell], true, castItem, triggeredByAura, originalCaster);
6845 break;
6846 }
6847 // Freya, Petrified Bark
6848 case 62933:
6849 case 62337:
6850 {
6851 if (!victim)
6852 return false;
6853
6854 int32 dmg = damage;
6855 victim->CastCustomSpell(this, 62379, &dmg, 0, 0, true);
6856 return true;
6857 }
6858 // Trial of the Champion, Earth Shield
6859 case 67534:
6860 {
6861 const int32 dmg = (int32)damage;
6862 CastCustomSpell(this, 67535, &dmg, nullptr, nullptr, true, 0, triggeredByAura, triggeredByAura->GetCasterGUID());
6863 return true;
6864 }
6865 // Trial of the Crusader, Faction Champions, Retaliation
6866 case 65932:
6867 {
6868 // check attack comes not from behind
6869 if (!victim || !HasInArc(M_PI, victim))
6870 return false;
6871
6872 triggered_spell_id = 65934;
6873 break;
6874 }
6875 // Pit of Saron, Tyrannus, Overlord's Brand
6876 case 69172: // everything except for DoTs
6877 {
6878 if (!target)
6879 return false;
6880 if (Unit* caster = triggeredByAura->GetCaster())
6881 {
6883 {
6884 int32 dmg = 5.5f * damage;
6885 target->CastCustomSpell(caster, 69190, &dmg, 0, 0, true);
6886 }
6887 else
6888 {
6889 if (caster->GetVictim())
6890 {
6891 int32 dmg = damage;
6892 target->CastCustomSpell(caster->GetVictim(), 69189, &dmg, 0, 0, true);
6893 }
6894 }
6895 }
6896 return true;
6897 }
6898 // Pit of Saron, Tyrannus, Overlord's Brand
6899 case 69173: // only DoTs
6900 {
6901 if (!target)
6902 return false;
6903 if (Unit* caster = triggeredByAura->GetCaster())
6904 {
6905 if (procEx & PROC_EX_INTERNAL_HOT)
6906 {
6907 int32 dmg = 5.5f * damage;
6908 target->CastCustomSpell(caster, 69190, &dmg, 0, 0, true);
6909 }
6910 else
6911 {
6912 if (caster->GetVictim())
6913 {
6914 int32 dmg = damage;
6915 target->CastCustomSpell(caster->GetVictim(), 69189, &dmg, 0, 0, true);
6916 }
6917 }
6918 }
6919 return true;
6920 }
6921 // Icecrown Citadel, Lady Deathwhisper, Vampiric Might
6922 case 70674:
6923 {
6924 if (Unit* caster = triggeredByAura->GetCaster())
6925 {
6926 int32 dmg = 3 * damage;
6927 caster->CastCustomSpell(caster, 70677, &dmg, 0, 0, true);
6928 }
6929 return true;
6930 }
6931 // Item: Purified Shard of the Gods
6932 case 69755:
6933 {
6934 triggered_spell_id = ((procFlag & PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_POS) ? 69733 : 69729);
6935 break;
6936 }
6937 // Item: Shiny Shard of the Gods
6938 case 69739:
6939 {
6940 triggered_spell_id = ((procFlag & PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_POS) ? 69734 : 69730);
6941 break;
6942 }
6943 // VoA: Meteor Fists koralon
6944 case 66725:
6945 case 68161:
6946 {
6947 triggered_spell_id = 66765; // handled by spell_difficulty
6948 break;
6949 }
6950 }
6951 break;
6952 }
6953 case SPELLFAMILY_MAGE:
6954 {
6955 // Magic Absorption
6956 if (dummySpell->SpellIconID == 459) // only this spell has SpellIconID == 459 and dummy aura
6957 {
6958 if (getPowerType() != POWER_MANA)
6959 return false;
6960
6961 // mana reward
6962 basepoints0 = CalculatePct(int32(GetMaxPower(POWER_MANA)), triggerAmount);
6963 target = this;
6964 triggered_spell_id = 29442;
6965 break;
6966 }
6967 // Hot Streak
6968 if (dummySpell->SpellIconID == 2999)
6969 {
6970 if (effIndex != 0)
6971 return false;
6972 AuraEffect* counter = triggeredByAura->GetBase()->GetEffect(EFFECT_1);
6973 if (!counter)
6974 return true;
6975
6976 // Count spell criticals in a row in second aura
6977 if (procEx & PROC_EX_CRITICAL_HIT)
6978 {
6979 counter->SetAmount(counter->GetAmount() * 2);
6980 if (counter->GetAmount() < 100) // not enough
6981 return true;
6982 // Crititcal counted -> roll chance
6983 if (roll_chance_i(triggerAmount))
6984 CastSpell(this, 48108, true, castItem, triggeredByAura);
6985 }
6986 counter->SetAmount(25);
6987 return true;
6988 }
6989 // Incanter's Regalia set (add trigger chance to Mana Shield)
6990 if (dummySpell->SpellFamilyFlags[0] & 0x8000)
6991 {
6992 if (GetTypeId() != TYPEID_PLAYER)
6993 return false;
6994
6995 target = this;
6996 triggered_spell_id = 37436;
6997 break;
6998 }
6999 switch (dummySpell->Id)
7000 {
7001 // Glyph of Polymorph
7002 case 56375:
7003 {
7004 if (!target)
7005 return false;
7006 target->RemoveAurasByType(SPELL_AURA_PERIODIC_DAMAGE, ObjectGuid::Empty, target->GetAura(32409)); // SW:D shall not be removed.
7009 return true;
7010 }
7011 // Glyph of Icy Veins
7012 case 56374:
7013 {
7016 return true;
7017 }
7018 // Glyph of Ice Block
7019 case 56372:
7020 {
7021 Player* player = ToPlayer();
7022 if (!player)
7023 return false;
7024
7025 SpellCooldowns const cooldowns = player->GetSpellCooldowns();
7026 // remove cooldowns on all ranks of Frost Nova
7027 for (SpellCooldowns::const_iterator itr = cooldowns.begin(); itr != cooldowns.end(); ++itr)
7028 {
7029 SpellInfo const* cdSpell = sSpellMgr->GetSpellInfo(itr->first);
7030 // Frost Nova
7031 if (cdSpell && cdSpell->SpellFamilyName == SPELLFAMILY_MAGE
7032 && cdSpell->SpellFamilyFlags[0] & 0x00000040)
7033 player->RemoveSpellCooldown(cdSpell->Id, true);
7034 }
7035 break;
7036 }
7037 }
7038 break;
7039 }
7041 {
7042 switch (dummySpell->Id)
7043 {
7044 // Victorious
7045 case 32216:
7046 {
7047 RemoveAura(dummySpell->Id);
7048 return false;
7049 }
7050 }
7051
7052 // Second Wind
7053 if (dummySpell->SpellIconID == 1697)
7054 {
7055 // only for spells and hit/crit (trigger start always) and not start from self casted spells (5530 Mace Stun Effect for example)
7056 if (procSpell == 0 || !(procEx & (PROC_EX_NORMAL_HIT | PROC_EX_CRITICAL_HIT)) || this == victim)
7057 return false;
7058 // Need stun or root mechanic
7059 if (!(procSpell->GetAllEffectsMechanicMask() & ((1 << MECHANIC_ROOT) | (1 << MECHANIC_STUN))))
7060 return false;
7061
7062 switch (dummySpell->Id)
7063 {
7064 case 29838:
7065 triggered_spell_id = 29842;
7066 break;
7067 case 29834:
7068 triggered_spell_id = 29841;
7069 break;
7070 case 42770:
7071 triggered_spell_id = 42771;
7072 break;
7073 default:
7074 LOG_ERROR("entities.unit", "Unit::HandleDummyAuraProc: non handled spell id: {} (SW)", dummySpell->Id);
7075 return false;
7076 }
7077
7078 target = this;
7079 break;
7080 }
7081 break;
7082 }
7084 {
7085 // Seed of Corruption
7086 if (dummySpell->SpellFamilyFlags[1] & 0x00000010)
7087 {
7088 if (procSpell && procSpell->SpellFamilyFlags[1] & 0x8000)
7089 return false;
7090 // if damage is more than need or target die from damage deal finish spell
7091 if (triggeredByAura->GetAmount() <= int32(damage) || GetHealth() <= damage)
7092 {
7093 // remember guid before aura delete
7094 ObjectGuid casterGuid = triggeredByAura->GetCasterGUID();
7095
7096 // Remove aura (before cast for prevent infinite loop handlers)
7097 RemoveAurasDueToSpell(triggeredByAura->GetId());
7098
7099 uint32 spell = sSpellMgr->GetSpellWithRank(27285, dummySpell->GetRank());
7100
7101 // Cast finish spell (triggeredByAura already not exist!)
7102 if (Unit* caster = ObjectAccessor::GetUnit(*this, casterGuid))
7103 {
7104 this->CastSpell(this, 37826, true); // VISUAL!
7105 caster->CastSpell(this, spell, true, castItem);
7106 }
7107
7108 return true; // no hidden cooldown
7109 }
7110
7111 // Damage counting
7112 triggeredByAura->SetAmount(triggeredByAura->GetAmount() - damage);
7113 return true;
7114 }
7115 // Seed of Corruption (Mobs cast) - no die req
7116 if (dummySpell->SpellFamilyFlags.IsEqual(0, 0, 0) && dummySpell->SpellIconID == 1932)
7117 {
7118 // if damage is more than need deal finish spell
7119 if (triggeredByAura->GetAmount() <= int32(damage))
7120 {
7121 // remember guid before aura delete
7122 ObjectGuid casterGuid = triggeredByAura->GetCasterGUID();
7123
7124 // Remove aura (before cast for prevent infinite loop handlers)
7125 RemoveAurasDueToSpell(triggeredByAura->GetId());
7126
7127 // Cast finish spell (triggeredByAura already not exist!)
7128 if (Unit* caster = ObjectAccessor::GetUnit(*this, casterGuid))
7129 {
7130 this->CastSpell(this, 37826, true); // VISUAL!
7131 caster->CastSpell(this, 32865, true, castItem);
7132 }
7133 return true; // no hidden cooldown
7134 }
7135 // Damage counting
7136 triggeredByAura->SetAmount(triggeredByAura->GetAmount() - damage);
7137 return true;
7138 }
7139 switch (dummySpell->Id)
7140 {
7141 // Nightfall
7142 case 18094:
7143 case 18095:
7144 // Glyph of corruption
7145 case 56218:
7146 {
7147 target = this;
7148 triggered_spell_id = 17941;
7149 break;
7150 }
7151 // Soul Leech
7152 case 30293:
7153 case 30295:
7154 case 30296:
7155 {
7156 // Improved Soul Leech
7157 AuraEffectList const& SoulLeechAuras = GetAuraEffectsByType(SPELL_AURA_DUMMY);
7158 for (Unit::AuraEffectList::const_iterator i = SoulLeechAuras.begin(); i != SoulLeechAuras.end(); ++i)
7159 {
7160 if ((*i)->GetId() == 54117 || (*i)->GetId() == 54118)
7161 {
7162 if ((*i)->GetEffIndex() != 0)
7163 continue;
7164 basepoints0 = int32((*i)->GetAmount());
7165 target = GetGuardianPet();
7166 if (target)
7167 {
7168 // regen mana for pet
7169 CastCustomSpell(target, 54607, &basepoints0, nullptr, nullptr, true, castItem, triggeredByAura);
7170 }
7171 // regen mana for caster
7172 CastCustomSpell(this, 59117, &basepoints0, nullptr, nullptr, true, castItem, triggeredByAura);
7173 // Get second aura of spell for replenishment effect on party
7174 if (AuraEffect const* aurEff = (*i)->GetBase()->GetEffect(EFFECT_1))
7175 {
7176 // Replenishment - roll chance
7177 if (roll_chance_i(aurEff->GetAmount()))
7178 {
7179 CastSpell(this, 57669, true, castItem, triggeredByAura);
7180 }
7181 }
7182 break;
7183 }
7184 }
7185 // health
7186 basepoints0 = CalculatePct(int32(damage), triggerAmount);
7187 target = this;
7188 triggered_spell_id = 30294;
7189 break;
7190 }
7191 // Shadowflame (Voidheart Raiment set bonus)
7192 case 37377:
7193 {
7194 triggered_spell_id = 37379;
7195 break;
7196 }
7197 // Pet Healing (Corruptor Raiment or Rift Stalker Armor)
7198 case 37381:
7199 {
7200 target = GetGuardianPet();
7201 if (!target)
7202 return false;
7203
7204 // heal amount
7205 basepoints0 = CalculatePct(int32(damage), triggerAmount);
7206 triggered_spell_id = 37382;
7207 break;
7208 }
7209 // Shadowflame Hellfire (Voidheart Raiment set bonus)
7210 case 39437:
7211 {
7212 triggered_spell_id = 37378;
7213 break;
7214 }
7215 }
7216 break;
7217 }
7218 case SPELLFAMILY_PRIEST:
7219 {
7220 // Body and Soul
7221 if (dummySpell->SpellIconID == 2218)
7222 {
7223 // Proc only from Abolish desease on self cast
7224 if (procSpell->Id != 552 || victim != this || !roll_chance_i(triggerAmount))
7225 return false;
7226 triggered_spell_id = 64136;
7227 target = this;
7228 break;
7229 }
7230 switch (dummySpell->Id)
7231 {
7232 // Vampiric Embrace
7233 case 15286:
7234 {
7235 if (!victim || !victim->IsAlive() || procSpell->SpellFamilyFlags[1] & 0x80000)
7236 return false;
7237
7238 // heal amount
7239 int32 total = CalculatePct(int32(damage), triggerAmount);
7240 int32 team = total / 5;
7241 int32 self = total - team;
7242 CastCustomSpell(this, 15290, &team, &self, nullptr, true, castItem, triggeredByAura);
7243 return true; // no hidden cooldown
7244 }
7245 // Priest Tier 6 Trinket (Ashtongue Talisman of Acumen)
7246 case 40438:
7247 {
7248 // Shadow Word: Pain
7249 if (procSpell->SpellFamilyFlags[0] & 0x8000)
7250 triggered_spell_id = 40441;
7251 // Renew
7252 else if (procSpell->SpellFamilyFlags[0] & 0x40)
7253 triggered_spell_id = 40440;
7254 else
7255 return false;
7256
7257 target = this;
7258 break;
7259 }
7260 // Improved Shadowform
7261 case 47570:
7262 case 47569:
7263 {
7264 if (!roll_chance_i(triggerAmount))
7265 return false;
7266
7268 break;
7269 }
7270 // Glyph of Dispel Magic
7271 case 55677:
7272 {
7273 // Dispel Magic shares spellfamilyflag with abolish disease
7274 if (procSpell->SpellIconID != 74)
7275 return false;
7276 if (!target || !target->IsFriendlyTo(this))
7277 return false;
7278
7279 basepoints0 = int32(target->CountPctFromMaxHealth(triggerAmount));
7280 triggered_spell_id = 56131;
7281 break;
7282 }
7283 // Oracle Healing Bonus ("Garments of the Oracle" set)
7284 case 26169:
7285 {
7286 // heal amount
7287 basepoints0 = int32(CalculatePct(damage, 10));
7288 target = this;
7289 triggered_spell_id = 26170;
7290 break;
7291 }
7292 // Frozen Shadoweave (Shadow's Embrace set) warning! its not only priest set
7293 case 39372:
7294 {
7295 if (!procSpell || (procSpell->GetSchoolMask() & (SPELL_SCHOOL_MASK_FROST | SPELL_SCHOOL_MASK_SHADOW)) == 0)
7296 return false;
7297
7298 // heal amount
7299 basepoints0 = CalculatePct(int32(damage), triggerAmount);
7300 target = this;
7301 triggered_spell_id = 39373;
7302 break;
7303 }
7304 // Greater Heal (Vestments of Faith (Priest Tier 3) - 4 pieces bonus)
7305 case 28809:
7306 {
7307 triggered_spell_id = 28810;
7308 break;
7309 }
7310 // Priest T10 Healer 2P Bonus
7311 case 70770:
7312 // Flash Heal
7313 if (procSpell->SpellFamilyFlags[0] & 0x800)
7314 {
7315 triggered_spell_id = 70772;
7316 SpellInfo const* blessHealing = sSpellMgr->GetSpellInfo(triggered_spell_id);
7317 if (!blessHealing || !victim)
7318 return false;
7319 basepoints0 = int32(CalculatePct(damage, triggerAmount) / (blessHealing->GetMaxDuration() / blessHealing->Effects[0].Amplitude));
7320 victim->CastDelayedSpellWithPeriodicAmount(this, triggered_spell_id, SPELL_AURA_PERIODIC_HEAL, basepoints0);
7321 return true;
7322 }
7323 break;
7324 }
7325 break;
7326 }
7327 case SPELLFAMILY_DRUID:
7328 {
7329 switch (dummySpell->Id)
7330 {
7331 // Glyph of Innervate
7332 case 54832:
7333 {
7334 if (procSpell->SpellIconID != 62)
7335 return false;
7336
7337 int32 mana_perc = triggeredByAura->GetSpellInfo()->Effects[triggeredByAura->GetEffIndex()].CalcValue();
7338 basepoints0 = int32(CalculatePct(GetCreatePowers(POWER_MANA), mana_perc) / 10);
7339 triggered_spell_id = 54833;
7340 target = this;
7341 break;
7342 }
7343 // Glyph of Starfire
7344 case 54845:
7345 {
7346 triggered_spell_id = 54846;
7347 break;
7348 }
7349 // Glyph of Shred
7350 case 54815:
7351 {
7352 if (!target)
7353 return false;
7354
7355 // try to find spell Rip on the target
7356 if (AuraEffect const* AurEff = target->GetAuraEffect(SPELL_AURA_PERIODIC_DAMAGE, SPELLFAMILY_DRUID, 0x00800000, 0x0, 0x0, GetGUID()))
7357 {
7358 // Rip's max duration, note: spells which modifies Rip's duration also counted like Glyph of Rip
7359 uint32 CountMin = AurEff->GetBase()->GetMaxDuration();
7360
7361 // just Rip's max duration without other spells
7362 uint32 CountMax = AurEff->GetSpellInfo()->GetMaxDuration();
7363
7364 // add possible auras' and Glyph of Shred's max duration
7365 CountMax += 3 * triggerAmount * IN_MILLISECONDS; // Glyph of Shred -> +6 seconds
7366 CountMax += HasAura(54818) ? 4 * IN_MILLISECONDS : 0; // Glyph of Rip -> +4 seconds
7367 CountMax += HasAura(60141) ? 4 * IN_MILLISECONDS : 0; // Rip Duration/Lacerate Damage -> +4 seconds
7368
7369 // if min < max -> that means caster didn't cast 3 shred yet
7370 // so set Rip's duration and max duration
7371 if (CountMin < CountMax)
7372 {
7373 AurEff->GetBase()->SetDuration(AurEff->GetBase()->GetDuration() + triggerAmount * IN_MILLISECONDS);
7374 AurEff->GetBase()->SetMaxDuration(CountMin + triggerAmount * IN_MILLISECONDS);
7375 return true;
7376 }
7377 }
7378 // if not found Rip
7379 return false;
7380 }
7381 // Glyph of Rake
7382 case 54821:
7383 {
7384 if (procSpell->SpellVisual[0] == 750 && procSpell->Effects[1].ApplyAuraName == 3)
7385 {
7386 if (target && target->GetTypeId() == TYPEID_UNIT)
7387 {
7388 triggered_spell_id = 54820;
7389 break;
7390 }
7391 }
7392 return false;
7393 }
7394 // Leader of the Pack
7395 case 24932:
7396 {
7397 if (triggerAmount <= 0)
7398 return false;
7399 basepoints0 = int32(CountPctFromMaxHealth(triggerAmount));
7400 target = this;
7401 triggered_spell_id = 34299;
7402 if (triggeredByAura->GetCasterGUID() != GetGUID())
7403 break;
7404 int32 basepoints1 = CalculatePct(GetMaxPower(Powers(POWER_MANA)), triggerAmount * 2);
7405 // Improved Leader of the Pack
7406 // Check cooldown of heal spell cooldown
7407 if (GetTypeId() == TYPEID_PLAYER && !ToPlayer()->HasSpellCooldown(34299))
7408 CastCustomSpell(this, 68285, &basepoints1, 0, 0, true, 0, triggeredByAura);
7409 break;
7410 }
7411 // Healing Touch (Dreamwalker Raiment set)
7412 case 28719:
7413 {
7414 // mana back
7415 basepoints0 = int32(CalculatePct(spellProc->GetPowerCost(), 30));
7416 target = this;
7417 triggered_spell_id = 28742;
7418 break;
7419 }
7420 // Glyph of Rejuvenation
7421 case 54754:
7422 {
7423 if (!victim || !victim->HealthBelowPct(uint32(triggerAmount)))
7424 return false;
7425 basepoints0 = CalculatePct(int32(damage), triggerAmount);
7426 triggered_spell_id = 54755;
7427 break;
7428 }
7429 // Healing Touch Refund (Idol of Longevity trinket)
7430 case 28847:
7431 {
7432 target = this;
7433 triggered_spell_id = 28848;
7434 break;
7435 }
7436 // Mana Restore (Malorne Raiment set / Malorne Regalia set)
7437 case 37288:
7438 case 37295:
7439 {
7440 target = this;
7441 triggered_spell_id = 37238;
7442 break;
7443 }
7444 // Druid Tier 6 Trinket
7445 case 40442:
7446 {
7447 float chance;
7448
7449 // Starfire
7450 if (procSpell->SpellFamilyFlags[0] & 0x4)
7451 {
7452 triggered_spell_id = 40445;
7453 chance = 25.0f;
7454 }
7455 // Rejuvenation
7456 else if (procSpell->SpellFamilyFlags[0] & 0x10)
7457 {
7458 triggered_spell_id = 40446;
7459 chance = 25.0f;
7460 }
7461 // Mangle (Bear) and Mangle (Cat)
7462 else if (procSpell->SpellFamilyFlags[1] & 0x00000440)
7463 {
7464 triggered_spell_id = 40452;
7465 chance = 40.0f;
7466 }
7467 else
7468 return false;
7469
7470 if (!roll_chance_f(chance))
7471 return false;
7472
7473 target = this;
7474 break;
7475 }
7476 // Maim Interrupt
7477 case 44835:
7478 {
7479 // Deadly Interrupt Effect
7480 triggered_spell_id = 32747;
7481 break;
7482 }
7483 // Item - Druid T10 Restoration 4P Bonus (Rejuvenation)
7484 case 70664:
7485 {
7486 // xinef: proc only from normal Rejuvenation, and proc rejuvenation
7487 if (!victim || !procSpell || procSpell->SpellIconID != 64)
7488 return false;
7489
7490 Player* caster = ToPlayer();
7491 if (!caster)
7492 return false;
7493 if (!caster->GetGroup() && victim == this)
7494 return false;
7495
7496 CastCustomSpell(70691, SPELLVALUE_BASE_POINT0, damage, victim, true);
7497 return true;
7498 }
7499 }
7500 // Eclipse
7501 if (dummySpell->SpellIconID == 2856 && GetTypeId() == TYPEID_PLAYER)
7502 {
7503 if (!procSpell || effIndex != 0)
7504 return false;
7505
7506 bool isWrathSpell = (procSpell->SpellFamilyFlags[0] & 1);
7507
7508 if (!roll_chance_f(dummySpell->ProcChance * (isWrathSpell ? 0.6f : 1.0f)))
7509 return false;
7510
7511 target = this;
7512 if (target->HasAura(isWrathSpell ? 48517 : 48518))
7513 return false;
7514
7515 triggered_spell_id = isWrathSpell ? 48518 : 48517;
7516 break;
7517 }
7518 [[fallthrough]]; // TODO: Not sure whether the fallthrough was a mistake (forgetting a break) or intended. This should be double-checked.
7519 }
7520 case SPELLFAMILY_ROGUE:
7521 {
7522 switch(dummySpell->Id)
7523 {
7524 // Glyph of Backstab
7525 case 56800:
7526 {
7527 if (victim)
7528 if (AuraEffect* aurEff = victim->GetAuraEffect(SPELL_AURA_PERIODIC_DAMAGE, SPELLFAMILY_ROGUE, 0x100000, 0, 0, GetGUID()))
7529 if (Aura* aur = aurEff->GetBase())
7530 if (!aur->IsRemoved() && aur->GetDuration() > 0)
7531 if ((aur->GetApplyTime() + aur->GetMaxDuration() / 1000 + 5) > (GameTime::GetGameTime().count() + aur->GetDuration() / 1000) )
7532 {
7533 aur->SetDuration(aur->GetDuration() + 2000);
7534 return true;
7535 }
7536 return false;
7537 }
7538 // Deadly Throw Interrupt
7539 case 32748:
7540 {
7541 // Prevent cast Deadly Throw Interrupt on self from last effect (apply dummy) of Deadly Throw
7542 if (this == victim)
7543 return false;
7544
7545 triggered_spell_id = 32747;
7546 break;
7547 }
7548 }
7549 // Master of subtlety
7550 if( dummySpell->SpellIconID == 2114 )
7551 {
7552 triggered_spell_id = 31665;
7553 basepoints0 = triggerAmount;
7554 break;
7555 }
7556 // Cut to the Chase
7557 if (dummySpell->SpellIconID == 2909)
7558 {
7559 // "refresh your Slice and Dice duration to its 5 combo point maximum"
7560 // lookup Slice and Dice
7561 if (AuraEffect const* aur = GetAuraEffect(SPELL_AURA_MOD_MELEE_HASTE, SPELLFAMILY_ROGUE, 0x40000, 0, 0))
7562 {
7563 aur->GetBase()->SetDuration(aur->GetSpellInfo()->GetMaxDuration(), true);
7564 return true;
7565 }
7566 return false;
7567 }
7568 // Deadly Brew
7569 else if (dummySpell->SpellIconID == 2963)
7570 {
7571 triggered_spell_id = 3409;
7572 break;
7573 }
7574 // Quick Recovery
7575 else if (dummySpell->SpellIconID == 2116)
7576 {
7577 if (!procSpell)
7578 return false;
7579
7580 // energy cost save
7581 basepoints0 = CalculatePct(int32(procSpell->ManaCost), triggerAmount);
7582 if (basepoints0 <= 0)
7583 return false;
7584
7585 target = this;
7586 triggered_spell_id = 31663;
7587 break;
7588 }
7589 break;
7590 }
7591 case SPELLFAMILY_HUNTER:
7592 {
7593 switch (dummySpell->SpellIconID)
7594 {
7595 case 2236: // Thrill of the Hunt
7596 {
7597 if (!procSpell)
7598 return false;
7599
7601
7602 // Disable charge drop because of Lock and Load
7603 if (spell)
7604 ToPlayer()->SetSpellModTakingSpell(spell, false);
7605
7606 // Explosive Shot
7607 if (procSpell->SpellFamilyFlags[2] & 0x200)
7608 {
7609 if (!victim)
7610 return false;
7611 if (AuraEffect const* pEff = victim->GetAuraEffect(SPELL_AURA_PERIODIC_DUMMY, SPELLFAMILY_HUNTER, 0x0, 0x80000000, 0x0, GetGUID()))
7612 basepoints0 = pEff->GetSpellInfo()->CalcPowerCost(this, SpellSchoolMask(pEff->GetSpellInfo()->SchoolMask)) * 4 / 10 / 3;
7613 }
7614 else
7615 basepoints0 = procSpell->CalcPowerCost(this, SpellSchoolMask(procSpell->SchoolMask)) * 4 / 10;
7616
7617 if (spell)
7618 ToPlayer()->SetSpellModTakingSpell(spell, true);
7619
7620 if (basepoints0 <= 0)
7621 return false;
7622
7623 target = this;
7624 triggered_spell_id = 34720;
7625 break;
7626 }
7627 case 3406: // Hunting Party
7628 {
7629 triggered_spell_id = 57669;
7630 target = this;
7631 break;
7632 }
7633 case 3560: // Rapid Recuperation
7634 {
7635 // This effect only from Rapid Killing (mana regen)
7636 if (!(procSpell->SpellFamilyFlags[1] & 0x01000000))
7637 return false;
7638
7639 target = this;
7640
7641 switch (dummySpell->Id)
7642 {
7643 case 53228: // Rank 1
7644 triggered_spell_id = 56654;
7645 break;
7646 case 53232: // Rank 2
7647 triggered_spell_id = 58882;
7648 break;
7649 }
7650 break;
7651 }
7652 }
7653
7654 switch (dummySpell->Id)
7655 {
7656 case 57870: // Glyph of Mend Pet
7657 {
7658 if (!victim)
7659 return false;
7660
7661 victim->CastSpell(victim, 57894, true, nullptr, nullptr, GetGUID());
7662 return true;
7663 }
7664 }
7665 break;
7666 }
7668 {
7669 // Light's Beacon - Beacon of Light
7670 if (dummySpell->Id == 53651)
7671 {
7672 if (!victim)
7673 return false;
7674
7675 // Do not proc from Glyph of Holy Light and Judgement of Light
7676 if (procSpell->Id == 20267 || procSpell->Id == 54968)
7677 {
7678 return false;
7679 }
7680
7681 Unit* beaconTarget = triggeredByAura->GetBase()->GetCaster();
7682 if (!beaconTarget || beaconTarget == this || !beaconTarget->GetAura(53563, victim->GetGUID()))
7683 return false;
7684
7685 basepoints0 = int32(damage);
7686 triggered_spell_id = procSpell->IsRankOf(sSpellMgr->GetSpellInfo(635)) ? 53652 : 53654;
7687
7688 victim->CastCustomSpell(beaconTarget, triggered_spell_id, &basepoints0, nullptr, nullptr, true, 0, triggeredByAura, victim->GetGUID());
7689 return true;
7690 }
7691 // Judgements of the Wise
7692 if (dummySpell->SpellIconID == 3017)
7693 {
7694 target = this;
7695 triggered_spell_id = 31930;
7696 // replenishment
7697 CastSpell(this, 57669, true, castItem, triggeredByAura);
7698 break;
7699 }
7700 // Righteous Vengeance
7701 if (dummySpell->SpellIconID == 3025)
7702 {
7703 if (!victim)
7704 return false;
7705
7706 // 4 damage tick
7707 basepoints0 = triggerAmount * damage / 400;
7708 triggered_spell_id = 61840;
7709 // Add remaining ticks to damage done
7710 victim->CastDelayedSpellWithPeriodicAmount(this, triggered_spell_id, SPELL_AURA_PERIODIC_DAMAGE, basepoints0);
7711 return true;
7712 }
7713 // Sheath of Light
7714 if (dummySpell->SpellIconID == 3030)
7715 {
7716 // 4 healing tick
7717 basepoints0 = triggerAmount * damage / 400;
7718 triggered_spell_id = 54203;
7719 break;
7720 }
7721 switch (dummySpell->Id)
7722 {
7723 // Judgement of Light
7724 case 20185:
7725 {
7726 if (!victim || !victim->IsAlive() || victim->HasSpellCooldown(20267))
7727 return false;
7728 // 2% of base mana
7729 basepoints0 = int32(victim->CountPctFromMaxHealth(2));
7730 victim->CastCustomSpell(victim, 20267, &basepoints0, 0, 0, true, 0, triggeredByAura);
7731 victim->AddSpellCooldown(20267, 0, 4 * IN_MILLISECONDS);
7732 return true;
7733 }
7734 // Judgement of Wisdom
7735 case 20186:
7736 {
7737 if (!victim || !victim->IsAlive() || victim->getPowerType() != POWER_MANA || victim->HasSpellCooldown(20268))
7738 return false;
7739
7740 // 2% of base mana
7741 basepoints0 = int32(CalculatePct(victim->GetCreateMana(), 2));
7742 victim->CastCustomSpell(victim, 20268, &basepoints0, nullptr, nullptr, true, 0, triggeredByAura);
7743 victim->AddSpellCooldown(20268, 0, 4 * IN_MILLISECONDS);
7744 return true;
7745 }
7746 // Holy Power (Redemption Armor set)
7747 case 28789:
7748 {
7749 if (!victim)
7750 return false;
7751
7752 // Set class defined buff
7753 switch (victim->getClass())
7754 {
7755 case CLASS_PALADIN:
7756 case CLASS_PRIEST:
7757 case CLASS_SHAMAN:
7758 case CLASS_DRUID:
7759 triggered_spell_id = 28795; // Increases the friendly target's mana regeneration by $s1 per 5 sec. for $d.
7760 break;
7761 case CLASS_MAGE:
7762 case CLASS_WARLOCK:
7763 triggered_spell_id = 28793; // Increases the friendly target's spell damage and healing by up to $s1 for $d.
7764 break;
7765 case CLASS_HUNTER:
7766 case CLASS_ROGUE:
7767 triggered_spell_id = 28791; // Increases the friendly target's attack power by $s1 for $d.
7768 break;
7769 case CLASS_WARRIOR:
7770 triggered_spell_id = 28790; // Increases the friendly target's armor
7771 break;
7772 default:
7773 return false;
7774 }
7775 break;
7776 }
7777 // Seal of Vengeance (damage calc on apply aura)
7778 case 31801:
7779 {
7780 if (effIndex != 0 || !victim) // effect 1, 2 used by seal unleashing code
7781 return false;
7782
7783 // At melee attack or Hammer of the Righteous spell damage considered as melee attack
7784 bool stacker = !procSpell || procSpell->Id == 53595;
7785 // spells with SPELL_DAMAGE_CLASS_MELEE excluding Judgements
7786 bool damager = procSpell && (procSpell->EquippedItemClass != -1 || (procSpell->SpellIconID == 243 && procSpell->SpellVisual[0] == 39));
7787
7788 if (!stacker && !damager)
7789 return false;
7790
7791 triggered_spell_id = 31803;
7792
7793 // On target with 5 stacks of Holy Vengeance direct damage is done
7794 if (Aura* aur = victim->GetAura(triggered_spell_id, GetGUID()))
7795 {
7796 if (aur->GetStackAmount() == 5)
7797 {
7798 if (stacker)
7799 aur->RefreshDuration();
7800
7801 CastSpell(victim, 42463, true, castItem, triggeredByAura);
7802 return true;
7803 }
7804 }
7805
7806 if (!stacker)
7807 return false;
7808 break;
7809 }
7810 // Seal of Corruption
7811 case 53736:
7812 {
7813 if (effIndex != 0 || !victim) // effect 1, 2 used by seal unleashing code
7814 return false;
7815
7816 // At melee attack or Hammer of the Righteous spell damage considered as melee attack
7817 bool stacker = !procSpell || procSpell->Id == 53595;
7818 // spells with SPELL_DAMAGE_CLASS_MELEE excluding Judgements
7819 bool damager = procSpell && (procSpell->EquippedItemClass != -1 || (procSpell->SpellIconID == 243 && procSpell->SpellVisual[0] == 39));
7820
7821 if (!stacker && !damager)
7822 return false;
7823
7824 triggered_spell_id = 53742;
7825
7826 // On target with 5 stacks of Blood Corruption direct damage is done
7827 if (Aura* aur = victim->GetAura(triggered_spell_id, GetGUID()))
7828 {
7829 if (aur->GetStackAmount() == 5)
7830 {
7831 if (stacker)
7832 aur->RefreshDuration();
7833
7834 CastSpell(victim, 53739, true, castItem, triggeredByAura);
7835 return true;
7836 }
7837 }
7838
7839 if (!stacker)
7840 return false;
7841 break;
7842 }
7843 // Spiritual Attunement
7844 case 31785:
7845 case 33776:
7846 {
7847 // if healed by another unit (victim)
7848 if (this == victim)
7849 return false;
7850
7851 // dont allow non-positive dots to proc
7852 if (!procSpell || !procSpell->IsPositive())
7853 return false;
7854
7855 // heal amount
7856 basepoints0 = int32(CalculatePct(std::min(damage, GetMaxHealth() - GetHealth()), triggerAmount));
7857 target = this;
7858
7859 if (basepoints0)
7860 triggered_spell_id = 31786;
7861 break;
7862 }
7863 // Paladin Tier 6 Trinket (Ashtongue Talisman of Zeal)
7864 case 40470:
7865 {
7866 if (!procSpell)
7867 return false;
7868
7869 float chance = 0.0f;
7870
7871 // Flash of light/Holy light
7872 if (procSpell->SpellFamilyFlags[0] & 0xC0000000)
7873 {
7874 triggered_spell_id = 40471;
7875 chance = 15.0f;
7876 }
7877 // Judgement (any)
7878 else if (procSpell->SpellFamilyFlags[0] & 0x800000)
7879 {
7880 triggered_spell_id = 40472;
7881 chance = 50.0f;
7882 }
7883 else
7884 return false;
7885
7886 if (!roll_chance_f(chance))
7887 return false;
7888
7889 break;
7890 }
7891 // Glyph of Holy Light
7892 case 54937:
7893 {
7894 triggered_spell_id = 54968;
7895 basepoints0 = CalculatePct(int32(damage), triggerAmount);
7896 break;
7897 }
7898 // Item - Paladin T8 Holy 2P Bonus
7899 case 64890:
7900 {
7901 triggered_spell_id = 64891;
7902 basepoints0 = triggerAmount * damage / 300;
7903 break;
7904 }
7905 case 71406: // Tiny Abomination in a Jar
7906 case 71545: // Tiny Abomination in a Jar (Heroic)
7907 {
7908 if (!victim || !victim->IsAlive())
7909 return false;
7910
7911 CastSpell(this, 71432, true, nullptr, triggeredByAura);
7912
7913 Aura const* dummy = GetAura(71432);
7914 if (!dummy || dummy->GetStackAmount() < (dummySpell->Id == 71406 ? 8 : 7))
7915 return false;
7916
7917 RemoveAurasDueToSpell(71432);
7918 triggered_spell_id = 71433; // default main hand attack
7919 // roll if offhand
7920 if (Player const* player = ToPlayer())
7921 if (player->GetWeaponForAttack(OFF_ATTACK, true) && urand(0, 1))
7922 triggered_spell_id = 71434;
7923 target = victim;
7924 break;
7925 }
7926 // Item - Icecrown 25 Normal Dagger Proc
7927 case 71880:
7928 {
7929 switch (getPowerType())
7930 {
7931 case POWER_MANA:
7932 triggered_spell_id = 71881;
7933 break;
7934 case POWER_RAGE:
7935 triggered_spell_id = 71883;
7936 break;
7937 case POWER_ENERGY:
7938 triggered_spell_id = 71882;
7939 break;
7940 case POWER_RUNIC_POWER:
7941 triggered_spell_id = 71884;
7942 break;
7943 default:
7944 return false;
7945 }
7946 break;
7947 }
7948 // Item - Icecrown 25 Heroic Dagger Proc
7949 case 71892:
7950 {
7951 switch (getPowerType())
7952 {
7953 case POWER_MANA:
7954 triggered_spell_id = 71888;
7955 break;
7956 case POWER_RAGE:
7957 triggered_spell_id = 71886;
7958 break;
7959 case POWER_ENERGY:
7960 triggered_spell_id = 71887;
7961 break;
7962 case POWER_RUNIC_POWER:
7963 triggered_spell_id = 71885;
7964 break;
7965 default:
7966 return false;
7967 }
7968 break;
7969 }
7970 }
7971 break;
7972 }
7973 case SPELLFAMILY_SHAMAN:
7974 {
7975 switch (dummySpell->Id)
7976 {
7977 // Tidal Force
7978 case 55198:
7979 {
7980 // Remove aura stack from caster
7981 RemoveAuraFromStack(55166);
7982 // drop charges
7983 return false;
7984 }
7985 // Totemic Power (The Earthshatterer set)
7986 case 28823:
7987 {
7988 if (!victim)
7989 return false;
7990
7991 // Set class defined buff
7992 switch (victim->getClass())
7993 {
7994 case CLASS_PALADIN:
7995 case CLASS_PRIEST:
7996 case CLASS_SHAMAN:
7997 case CLASS_DRUID:
7998 triggered_spell_id = 28824; // Increases the friendly target's mana regeneration by $s1 per 5 sec. for $d.
7999 break;
8000 case CLASS_MAGE:
8001 case CLASS_WARLOCK:
8002 triggered_spell_id = 28825; // Increases the friendly target's spell damage and healing by up to $s1 for $d.
8003 break;
8004 case CLASS_HUNTER:
8005 case CLASS_ROGUE:
8006 triggered_spell_id = 28826; // Increases the friendly target's attack power by $s1 for $d.
8007 break;
8008 case CLASS_WARRIOR:
8009 triggered_spell_id = 28827; // Increases the friendly target's armor
8010 break;
8011 default:
8012 return false;
8013 }
8014 break;
8015 }
8016 // Lesser Healing Wave (Totem of Flowing Water Relic)
8017 case 28849:
8018 {
8019 target = this;
8020 triggered_spell_id = 28850;
8021 break;
8022 }
8023 // Windfury Weapon (Passive) 1-8 Ranks
8024 case 33757:
8025 {
8026 Player* player = ToPlayer();
8027 if (!player || !castItem || !castItem->IsEquipped() || !victim || !victim->IsAlive())
8028 return false;
8029
8030 if (triggeredByAura->GetBase() && castItem->GetGUID() != triggeredByAura->GetBase()->GetCastItemGUID())
8031 return false;
8032
8033 WeaponAttackType attType = WeaponAttackType(player->GetAttackBySlot(castItem->GetSlot()));
8034 if ((attType != BASE_ATTACK && attType != OFF_ATTACK)
8035 || (attType == BASE_ATTACK && procFlag & PROC_FLAG_DONE_OFFHAND_ATTACK)
8036 || (attType == OFF_ATTACK && procFlag & PROC_FLAG_DONE_MAINHAND_ATTACK))
8037 return false;
8038
8039 // Now amount of extra power stored in 1 effect of Enchant spell
8040 // Get it by item enchant id
8041 uint32 spellId;
8043 {
8044 case 283:
8045 spellId = 8232;
8046 break; // 1 Rank
8047 case 284:
8048 spellId = 8235;
8049 break; // 2 Rank
8050 case 525:
8051 spellId = 10486;
8052 break; // 3 Rank
8053 case 1669:
8054 spellId = 16362;
8055 break; // 4 Rank
8056 case 2636:
8057 spellId = 25505;
8058 break; // 5 Rank
8059 case 3785:
8060 spellId = 58801;
8061 break; // 6 Rank
8062 case 3786:
8063 spellId = 58803;
8064 break; // 7 Rank
8065 case 3787:
8066 spellId = 58804;
8067 break; // 8 Rank
8068 default:
8069 {
8070 LOG_ERROR("entities.unit", "Unit::HandleDummyAuraProc: non handled item enchantment (rank?) {} for spell id: {} (Windfury)",
8071 castItem->GetEnchantmentId(EnchantmentSlot(TEMP_ENCHANTMENT_SLOT)), dummySpell->Id);
8072 return false;
8073 }
8074 }
8075
8076 SpellInfo const* windfurySpellInfo = sSpellMgr->GetSpellInfo(spellId);
8077 if (!windfurySpellInfo)
8078 {
8079 LOG_ERROR("entities.unit", "Unit::HandleDummyAuraProc: non-existing spell id: {} (Windfury)", spellId);
8080 return false;
8081 }
8082
8083 int32 extra_attack_power = CalculateSpellDamage(victim, windfurySpellInfo, 1);
8084
8085 // Value gained from additional AP
8086 basepoints0 = int32(extra_attack_power / 14.0f * GetAttackTime(attType) / 1000);
8087
8088 if (procFlag & PROC_FLAG_DONE_MAINHAND_ATTACK)
8089 triggered_spell_id = 25504;
8090
8091 if (procFlag & PROC_FLAG_DONE_OFFHAND_ATTACK)
8092 triggered_spell_id = 33750;
8093
8094 // custom cooldown processing case
8095 if (player->HasSpellCooldown(dummySpell->Id))
8096 return false;
8097
8098 // apply cooldown before cast to prevent processing itself
8099 player->AddSpellCooldown(dummySpell->Id, 0, 3 * IN_MILLISECONDS);
8100
8101 // Attack Twice
8102 for (uint32 i = 0; i < 2; ++i)
8103 CastCustomSpell(victim, triggered_spell_id, &basepoints0, nullptr, nullptr, true, castItem, triggeredByAura);
8104
8105 return true;
8106 }
8107 // Shaman Tier 6 Trinket
8108 case 40463:
8109 {
8110 if (!procSpell)
8111 return false;
8112
8113 float chance;
8114 if (procSpell->SpellFamilyFlags[0] & 0x1)
8115 {
8116 triggered_spell_id = 40465; // Lightning Bolt
8117 chance = 15.0f;
8118 }
8119 else if (procSpell->SpellFamilyFlags[0] & 0x80)
8120 {
8121 triggered_spell_id = 40465; // Lesser Healing Wave
8122 chance = 10.0f;
8123 }
8124 else if (procSpell->SpellFamilyFlags[1] & 0x00000010)
8125 {
8126 triggered_spell_id = 40466; // Stormstrike
8127 chance = 50.0f;
8128 }
8129 else
8130 return false;
8131
8132 if (!roll_chance_f(chance))
8133 return false;
8134
8135 target = this;
8136 break;
8137 }
8138 // Glyph of Healing Wave
8139 case 55440:
8140 {
8141 // Not proc from self heals
8142 if (this == victim)
8143 return false;
8144 basepoints0 = CalculatePct(int32(damage), triggerAmount);
8145 target = this;
8146 triggered_spell_id = 55533;
8147 break;
8148 }
8149 // Spirit Hunt
8150 case 58877:
8151 {
8152 // Cast on owner
8153 target = GetOwner();
8154 if (!target)
8155 return false;
8156 basepoints0 = CalculatePct(int32(damage), triggerAmount);
8157 triggered_spell_id = 58879;
8158 // Heal wolf
8159 CastCustomSpell(this, triggered_spell_id, &basepoints0, nullptr, nullptr, true, castItem, triggeredByAura, originalCaster);
8160 break;
8161 }
8162 // Shaman T8 Elemental 4P Bonus
8163 case 64928:
8164 {
8165 basepoints0 = CalculatePct(int32(damage), triggerAmount);
8166 triggered_spell_id = 64930; // Electrified
8167 break;
8168 }
8169 // Shaman T9 Elemental 4P Bonus
8170 case 67228:
8171 {
8172 // Lava Burst
8173 if (procSpell->SpellFamilyFlags[1] & 0x1000)
8174 {
8175 triggered_spell_id = 71824;
8176 SpellInfo const* triggeredSpell = sSpellMgr->GetSpellInfo(triggered_spell_id);
8177 if (!triggeredSpell)
8178 return false;
8179 basepoints0 = CalculatePct(int32(damage), triggerAmount) / (triggeredSpell->GetMaxDuration() / triggeredSpell->Effects[0].Amplitude);
8180 }
8181 break;
8182 }
8183 // Item - Shaman T10 Elemental 4P Bonus
8184 case 70817:
8185 {
8186 if (!target)
8187 return false;
8188 // try to find spell Flame Shock on the target
8189 if (AuraEffect const* aurEff = target->GetAuraEffect(SPELL_AURA_PERIODIC_DAMAGE, SPELLFAMILY_SHAMAN, 0x10000000, 0x0, 0x0, GetGUID()))
8190 {
8191 Aura* flameShock = aurEff->GetBase();
8192 int32 extraTime = 2 * aurEff->GetAmplitude();
8193 flameShock->SetMaxDuration(flameShock->GetMaxDuration() + extraTime);
8194 flameShock->SetDuration(flameShock->GetDuration() + extraTime);
8195
8196 return true;
8197 }
8198 // if not found Flame Shock
8199 return false;
8200 }
8201 break;
8202 }
8203 // Frozen Power
8204 if (dummySpell->SpellIconID == 3780)
8205 {
8206 if (!target)
8207 return false;
8208 if (GetDistance(target) < 15.0f)
8209 return false;
8210 float chance = (float)triggerAmount;
8211 if (!roll_chance_f(chance))
8212 return false;
8213
8214 triggered_spell_id = 63685;
8215 break;
8216 }
8217 // Ancestral Awakening
8218 if (dummySpell->SpellIconID == 3065)
8219 {
8220 triggered_spell_id = 52759;
8221 basepoints0 = CalculatePct(int32(damage), triggerAmount);
8222 target = this;
8223 break;
8224 }
8225 // Flametongue Weapon (Passive)
8226 if (dummySpell->SpellFamilyFlags[0] & 0x200000)
8227 {
8228 if (GetTypeId() != TYPEID_PLAYER || !victim || !victim->IsAlive() || !castItem || !castItem->IsEquipped())
8229 return false;
8230
8232 if ((attType != BASE_ATTACK && attType != OFF_ATTACK)
8233 || (attType == BASE_ATTACK && procFlag & PROC_FLAG_DONE_OFFHAND_ATTACK)
8234 || (attType == OFF_ATTACK && procFlag & PROC_FLAG_DONE_MAINHAND_ATTACK))
8235 return false;
8236
8237 float fire_onhit = float(CalculatePct(dummySpell->Effects[EFFECT_0]. CalcValue(), 1.0f));
8238
8239 float add_spellpower = (float)(SpellBaseDamageBonusDone(SPELL_SCHOOL_MASK_FIRE)
8241
8242 // 1.3speed = 5%, 2.6speed = 10%, 4.0 speed = 15%, so, 1.0speed = 3.84%
8243 ApplyPct(add_spellpower, 3.84f);
8244
8245 // Enchant on Off-Hand and ready?
8246 if (castItem->GetSlot() == EQUIPMENT_SLOT_OFFHAND && procFlag & PROC_FLAG_DONE_OFFHAND_ATTACK)
8247 {
8248 float BaseWeaponSpeed = GetAttackTime(OFF_ATTACK) / 1000.0f;
8249
8250 // Value1: add the tooltip damage by swingspeed + Value2: add spelldmg by swingspeed
8251 basepoints0 = int32((fire_onhit * BaseWeaponSpeed) + (add_spellpower * BaseWeaponSpeed));
8252 triggered_spell_id = 10444;
8253 }
8254
8255 // Enchant on Main-Hand and ready?
8256 else if (castItem->GetSlot() == EQUIPMENT_SLOT_MAINHAND && procFlag & PROC_FLAG_DONE_MAINHAND_ATTACK)
8257 {
8258 float BaseWeaponSpeed = GetAttackTime(BASE_ATTACK) / 1000.0f;
8259
8260 // Value1: add the tooltip damage by swingspeed + Value2: add spelldmg by swingspeed
8261 basepoints0 = int32((fire_onhit * BaseWeaponSpeed) + (add_spellpower * BaseWeaponSpeed));
8262 triggered_spell_id = 10444;
8263 }
8264
8265 // If not ready, we should return, shouldn't we?!
8266 else
8267 return false;
8268
8269 CastCustomSpell(victim, triggered_spell_id, &basepoints0, nullptr, nullptr, true, castItem, triggeredByAura);
8270 return true;
8271 }
8272 // Improved Water Shield
8273 if (dummySpell->SpellIconID == 2287)
8274 {
8275 if (!procSpell)
8276 return false;
8277
8278 // Default chance for Healing Wave and Riptide
8279 float chance = (float)triggeredByAura->GetAmount();
8280
8281 if (procSpell->SpellFamilyFlags[0] & 0x80)
8282 // Lesser Healing Wave - 0.6 of default
8283 chance *= 0.6f;
8284 else if (procSpell->SpellFamilyFlags[0] & 0x100)
8285 // Chain heal - 0.3 of default
8286 chance *= 0.3f;
8287
8288 if (!roll_chance_f(chance))
8289 return false;
8290
8291 // Water Shield
8292 if (AuraEffect const* aurEff = GetAuraEffect(SPELL_AURA_PROC_TRIGGER_SPELL, SPELLFAMILY_SHAMAN, 0, 0x00000020, 0))
8293 {
8294 uint32 spell = aurEff->GetSpellInfo()->Effects[aurEff->GetEffIndex()].TriggerSpell;
8295 CastSpell(this, spell, true, castItem, triggeredByAura);
8296 return true;
8297 }
8298 return false;
8299 }
8300 // Lightning Overload
8301 if (dummySpell->SpellIconID == 2018) // only this spell have SpellFamily Shaman SpellIconID == 2018 and dummy aura
8302 {
8303 if(!procSpell || GetTypeId() != TYPEID_PLAYER || !victim)
8304 return false;
8305
8306 if (procEx & PROC_EX_CRITICAL_HIT)
8307 damage /= 2;
8308
8309 do
8310 {
8311 uint32 spell = 0;
8312
8313 if (procSpell->SpellFamilyFlags[0] & 0x2)
8314 {
8315 // 1/3 of 33% if 11%
8316 if (!roll_chance_i(33))
8317 return false;
8318
8319 spell = 45297;
8320 }
8321 else
8322 spell = 45284;
8323
8324 // do not reduce damage-spells have correct basepoints
8325 damage /= 2;
8326 int32 dmg = damage;
8327
8328 // Cast
8329 CastCustomSpell(victim, spell, &dmg, 0, 0, true, castItem, triggeredByAura);
8330 } while (roll_chance_i(33));
8331 return true;
8332 }
8333 // Static Shock
8334 if (dummySpell->SpellIconID == 3059)
8335 {
8336 // Lightning Shield
8338 {
8339 uint32 spell = sSpellMgr->GetSpellWithRank(26364, aurEff->GetSpellInfo()->GetRank());
8340 CastSpell(target, spell, true, castItem, triggeredByAura);
8341 aurEff->GetBase()->DropCharge();
8342 return true;
8343 }
8344 return false;
8345 }
8346 break;
8347 }
8349 {
8350 // Improved Blood Presence
8351 if (dummySpell->SpellIconID == 2636)
8352 {
8353 if (GetTypeId() != TYPEID_PLAYER)
8354 return false;
8355 basepoints0 = CalculatePct(int32(damage), triggerAmount);
8356 break;
8357 }
8358 // Butchery
8359 if (dummySpell->SpellIconID == 2664)
8360 {
8361 basepoints0 = triggerAmount;
8362 triggered_spell_id = 50163;
8363 target = this;
8364 break;
8365 }
8366 // Mark of Blood
8367 if (dummySpell->Id == 49005)
8368 {
8369 // TODO: need more info (cooldowns/PPM)
8370 triggered_spell_id = 61607;
8371 break;
8372 }
8373 // Unholy Blight
8374 if (dummySpell->Id == 49194)
8375 {
8376 triggered_spell_id = 50536;
8377 SpellInfo const* unholyBlight = sSpellMgr->GetSpellInfo(triggered_spell_id);
8378 if (!unholyBlight || !victim)
8379 return false;
8380
8381 basepoints0 = CalculatePct(int32(damage), triggerAmount);
8382
8383 //Glyph of Unholy Blight
8384 if (AuraEffect* glyph = GetAuraEffect(63332, 0))
8385 AddPct(basepoints0, glyph->GetAmount());
8386
8387 basepoints0 = basepoints0 / (unholyBlight->GetMaxDuration() / unholyBlight->Effects[0].Amplitude);
8388 victim->CastDelayedSpellWithPeriodicAmount(this, triggered_spell_id, SPELL_AURA_PERIODIC_DAMAGE, basepoints0);
8389 return true;
8390 }
8391 // Vendetta
8392 if (dummySpell->SpellFamilyFlags[0] & 0x10000)
8393 {
8394 basepoints0 = int32(CountPctFromMaxHealth(triggerAmount));
8395 triggered_spell_id = 50181;
8396 target = this;
8397 break;
8398 }
8399 // Necrosis
8400 if (dummySpell->SpellIconID == 2709)
8401 {
8402 basepoints0 = CalculatePct(int32(damage), triggerAmount);
8403 triggered_spell_id = 51460;
8404 break;
8405 }
8406 // Threat of Thassarian
8407 if (dummySpell->SpellIconID == 2023)
8408 {
8409 // Must Dual Wield
8410 if (!procSpell || !haveOffhandWeapon())
8411 return false;
8412 // Chance as basepoints for dummy aura
8413 if (!roll_chance_i(triggerAmount))
8414 return false;
8415
8416 switch (procSpell->Id)
8417 {
8418 // Obliterate
8419 case 49020:
8420 triggered_spell_id = 66198;
8421 break; // Rank 1
8422 case 51423:
8423 triggered_spell_id = 66972;
8424 break; // Rank 2
8425 case 51424:
8426 triggered_spell_id = 66973;
8427 break; // Rank 3
8428 case 51425:
8429 triggered_spell_id = 66974;
8430 break; // Rank 4
8431
8432 // Frost Strike
8433 case 49143:
8434 triggered_spell_id = 66196;
8435 break; // Rank 1
8436 case 51416:
8437 triggered_spell_id = 66958;
8438 break; // Rank 2
8439 case 51417:
8440 triggered_spell_id = 66959;
8441 break; // Rank 3
8442 case 51418:
8443 triggered_spell_id = 66960;
8444 break; // Rank 4
8445 case 51419:
8446 triggered_spell_id = 66961;
8447 break; // Rank 5
8448 case 55268:
8449 triggered_spell_id = 66962;
8450 break; // Rank 6
8451
8452 // Plague Strike
8453 case 45462:
8454 triggered_spell_id = 66216;
8455 break; // Rank 1
8456 case 49917:
8457 triggered_spell_id = 66988;
8458 break; // Rank 2
8459 case 49918:
8460 triggered_spell_id = 66989;
8461 break; // Rank 3
8462 case 49919:
8463 triggered_spell_id = 66990;
8464 break; // Rank 4
8465 case 49920:
8466 triggered_spell_id = 66991;
8467 break; // Rank 5
8468 case 49921:
8469 triggered_spell_id = 66992;
8470 break; // Rank 6
8471
8472 // Death Strike
8473 case 49998:
8474 triggered_spell_id = 66188;
8475 break; // Rank 1
8476 case 49999:
8477 triggered_spell_id = 66950;
8478 break; // Rank 2
8479 case 45463:
8480 triggered_spell_id = 66951;
8481 break; // Rank 3
8482 case 49923:
8483 triggered_spell_id = 66952;
8484 break; // Rank 4
8485 case 49924:
8486 triggered_spell_id = 66953;
8487 break; // Rank 5
8488
8489 // Rune Strike
8490 case 56815:
8491 triggered_spell_id = 66217;
8492 break; // Rank 1
8493
8494 // Blood Strike
8495 case 45902:
8496 triggered_spell_id = 66215;
8497 break; // Rank 1
8498 case 49926:
8499 triggered_spell_id = 66975;
8500 break; // Rank 2
8501 case 49927:
8502 triggered_spell_id = 66976;
8503 break; // Rank 3
8504 case 49928:
8505 triggered_spell_id = 66977;
8506 break; // Rank 4
8507 case 49929:
8508 triggered_spell_id = 66978;
8509 break; // Rank 5
8510 case 49930:
8511 triggered_spell_id = 66979;
8512 break; // Rank 6
8513 default:
8514 return false;
8515 }
8516
8517 // This should do, restore spell mod so next attack can also use this!
8518 // crit chance for first strike is already computed
8519 ToPlayer()->RestoreSpellMods(m_currentSpells[CURRENT_GENERIC_SPELL], 51124, nullptr); // Killing Machine
8520 ToPlayer()->RestoreSpellMods(m_currentSpells[CURRENT_GENERIC_SPELL], 49796, nullptr); // Deathchill
8521
8522 // Xinef: Somehow basepoints are divided by 2 which is later divided by 2 (offhand multiplier)
8523 SpellInfo const* triggerEntry = sSpellMgr->GetSpellInfo(triggered_spell_id);
8524 if (triggerEntry->SchoolMask & SPELL_SCHOOL_MASK_NORMAL)
8525 basepoints0 = triggerEntry->Effects[EFFECT_0].BasePoints * 2;
8526
8527 SetCantProc(true);
8528 if(basepoints0)
8529 CastCustomSpell(target, triggered_spell_id, &basepoints0, nullptr, nullptr, true, castItem, triggeredByAura, originalCaster);
8530 else
8531 CastSpell(target, triggered_spell_id, true, castItem, triggeredByAura, originalCaster);
8532 SetCantProc(false);
8533 return true;
8534 }
8535 // Runic Power Back on Snare/Root
8536 if (dummySpell->Id == 61257)
8537 {
8538 // only for spells and hit/crit (trigger start always) and not start from self casted spells
8539 if (procSpell == 0 || !(procEx & (PROC_EX_NORMAL_HIT | PROC_EX_CRITICAL_HIT)) || this == victim)
8540 return false;
8541 // Need snare or root mechanic
8542 if (!(procSpell->GetAllEffectsMechanicMask() & ((1 << MECHANIC_ROOT) | (1 << MECHANIC_SNARE))))
8543 return false;
8544 triggered_spell_id = 61258;
8545 target = this;
8546 break;
8547 }
8548 // Sudden Doom
8549 if (dummySpell->SpellIconID == 1939 && GetTypeId() == TYPEID_PLAYER)
8550 {
8551 SpellChainNode const* chain = nullptr;
8552 // get highest rank of the Death Coil spell
8553 PlayerSpellMap const& sp_list = ToPlayer()->GetSpellMap();
8554 for (PlayerSpellMap::const_iterator itr = sp_list.begin(); itr != sp_list.end(); ++itr)
8555 {
8556 // check if shown in spell book
8557 if (!itr->second->Active || !itr->second->IsInSpec(ToPlayer()->GetActiveSpec()) || itr->second->State == PLAYERSPELL_REMOVED)
8558 continue;
8559
8560 SpellInfo const* spellProto = sSpellMgr->GetSpellInfo(itr->first);
8561 if (!spellProto)
8562 continue;
8563
8564 if (spellProto->SpellFamilyName == SPELLFAMILY_DEATHKNIGHT
8565 && spellProto->SpellFamilyFlags[0] & 0x2000)
8566 {
8567 SpellChainNode const* newChain = sSpellMgr->GetSpellChainNode(itr->first);
8568
8569 // No chain entry or entry lower than found entry
8570 if (!chain || !newChain || (chain->rank < newChain->rank))
8571 {
8572 triggered_spell_id = itr->first;
8573 chain = newChain;
8574 }
8575 else
8576 continue;
8577 // Found spell is last in chain - do not need to look more
8578 // Optimisation for most common case
8579 if (chain && chain->last->Id == itr->first)
8580 break;
8581 }
8582 }
8583 }
8584 break;
8585 }
8586 case SPELLFAMILY_POTION:
8587 {
8588 // alchemist's stone
8589 if (dummySpell->Id == 17619)
8590 {
8591 if (procSpell->SpellFamilyName == SPELLFAMILY_POTION)
8592 {
8593 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; i++)
8594 {
8595 if (procSpell->Effects[i].Effect == SPELL_EFFECT_HEAL)
8596 {
8597 triggered_spell_id = 21399;
8598 }
8599 else if (procSpell->Effects[i].Effect == SPELL_EFFECT_ENERGIZE)
8600 {
8601 triggered_spell_id = 21400;
8602 }
8603 else
8604 continue;
8605
8606 basepoints0 = int32(CalculateSpellDamage(this, procSpell, i) * 0.4f);
8607 CastCustomSpell(this, triggered_spell_id, &basepoints0, nullptr, nullptr, true, nullptr, triggeredByAura);
8608 }
8609 return true;
8610 }
8611 }
8612 break;
8613 }
8614 case SPELLFAMILY_PET:
8615 {
8616 switch (dummySpell->SpellIconID)
8617 {
8618 // Guard Dog
8619 case 201:
8620 {
8621 if (!victim)
8622 return false;
8623
8624 triggered_spell_id = 54445;
8625 target = this;
8626 float addThreat = float(CalculatePct(procSpell->Effects[0].CalcValue(this), triggerAmount));
8627 victim->AddThreat(this, addThreat);
8628 break;
8629 }
8630 // Silverback
8631 case 1582:
8632 triggered_spell_id = dummySpell->Id == 62765 ? 62801 : 62800;
8633 target = this;
8634 break;
8635 }
8636 break;
8637 }
8638 default:
8639 break;
8640 }
8641
8642 // if not handled by custom case, get triggered spell from dummySpell proto
8643 if (!triggered_spell_id)
8644 triggered_spell_id = dummySpell->Effects[triggeredByAura->GetEffIndex()].TriggerSpell;
8645
8646 // processed charge only counting case
8647 if (!triggered_spell_id)
8648 return true;
8649
8650 SpellInfo const* triggerEntry = sSpellMgr->GetSpellInfo(triggered_spell_id);
8651 if (!triggerEntry)
8652 {
8653 LOG_ERROR("entities.unit", "Unit::HandleDummyAuraProc: Spell {} has non-existing triggered spell {}", dummySpell->Id, triggered_spell_id);
8654 return false;
8655 }
8656
8657 if (cooldown_spell_id == 0)
8658 cooldown_spell_id = triggered_spell_id;
8659
8660 if (cooldown)
8661 {
8662 if (HasSpellCooldown(cooldown_spell_id))
8663 return false;
8664
8665 AddSpellCooldown(cooldown_spell_id, 0, cooldown);
8666 }
8667
8668 if(basepoints0)
8669 CastCustomSpell(target, triggered_spell_id, &basepoints0, nullptr, nullptr, true, castItem, triggeredByAura, originalCaster);
8670 else
8671 CastSpell(target, triggered_spell_id, true, castItem, triggeredByAura, originalCaster);
8672
8673 return true;
8674}
constexpr auto IN_MILLISECONDS
Definition: Common.h:62
static First const & RAND(First const &first, Second const &second, Rest const &... rest)
Definition: CreatureAIImpl.h:30
EnchantmentSlot
Definition: Item.h:162
@ TEMP_ENCHANTMENT_SLOT
Definition: Item.h:164
std::map< uint32, SpellCooldown > SpellCooldowns
Definition: Player.h:209
std::unordered_map< uint32, PlayerSpell * > PlayerSpellMap
Definition: Player.h:194
@ EQUIPMENT_SLOT_MAINHAND
Definition: Player.h:691
@ PLAYERSPELL_REMOVED
Definition: Player.h:123
int32 irand(int32 min, int32 max)
Definition: Random.cpp:37
@ SPELL_EFFECT_ENERGIZE
Definition: SharedDefines.h:780
@ LANG_UNIVERSAL
Definition: SharedDefines.h:707
@ CLASS_DRUID
Definition: SharedDefines.h:123
@ CLASS_SHAMAN
Definition: SharedDefines.h:119
@ CLASS_PRIEST
Definition: SharedDefines.h:117
@ CLASS_WARLOCK
Definition: SharedDefines.h:121
@ CLASS_MAGE
Definition: SharedDefines.h:120
@ CLASS_PALADIN
Definition: SharedDefines.h:114
@ CLASS_ROGUE
Definition: SharedDefines.h:116
@ MECHANIC_STUN
Definition: SharedDefines.h:1309
@ MECHANIC_ROOT
Definition: SharedDefines.h:1304
@ MECHANIC_SNARE
Definition: SharedDefines.h:1308
@ SPELLFAMILY_WARLOCK
Definition: SharedDefines.h:3505
@ SPELLFAMILY_PALADIN
Definition: SharedDefines.h:3510
@ SPELLFAMILY_HUNTER
Definition: SharedDefines.h:3509
@ SPELLFAMILY_POTION
Definition: SharedDefines.h:3513
@ SPELLFAMILY_ROGUE
Definition: SharedDefines.h:3508
@ SPELLFAMILY_DRUID
Definition: SharedDefines.h:3507
@ SPELLFAMILY_PET
Definition: SharedDefines.h:3517
@ REP_EXALTED
Definition: SharedDefines.h:159
@ SPELL_SCHOOL_MASK_SHADOW
Definition: SharedDefines.h:274
@ SPELL_SCHOOL_MASK_FIRE
Definition: SharedDefines.h:271
@ SPELL_SCHOOL_MASK_FROST
Definition: SharedDefines.h:273
@ SPELL_AURA_PROC_TRIGGER_SPELL
Definition: SpellAuraDefines.h:105
@ SPELL_AURA_HASTE_SPELLS
Definition: SpellAuraDefines.h:279
@ SPELL_AURA_MOD_MELEE_HASTE
Definition: SpellAuraDefines.h:201
@ SPELL_AURA_MOD_DECREASE_SPEED
Definition: SpellAuraDefines.h:96
@ SPELL_AURA_PERIODIC_DUMMY
Definition: SpellAuraDefines.h:289
@ PROC_EX_INTERNAL_HOT
Definition: SpellMgr.h:220
@ PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_POS
Definition: SpellMgr.h:128
@ PROC_FLAG_DONE_SPELL_NONE_DMG_CLASS_POS
Definition: SpellMgr.h:122
WeaponAttackType
Definition: Unit.h:395
T ApplyPct(T &base, U pct)
Definition: Util.h:73
void SetMaxDuration(int32 duration)
Definition: SpellAuras.h:130
uint8 GetSlot() const
Definition: Item.h:272
uint32 GetEnchantmentId(EnchantmentSlot slot) const
Definition: Item.h:295
bool IsEquipped() const
Definition: Item.cpp:791
void SetSpellModTakingSpell(Spell *spell, bool apply)
Definition: Player.cpp:9807
void RestoreSpellMods(Spell *spell, uint32 ownerAuraId=0, Aura *aura=nullptr)
Definition: Player.cpp:9667
bool HasSpellCooldown(uint32 spell_id) const override
Definition: Player.cpp:16022
PlayerSpellMap const & GetSpellMap() const
Definition: Player.h:1726
void AddSpellCooldown(uint32 spell_id, uint32 itemid, uint32 end_time, bool needSendToClient=false, bool forceSendToSpectator=false) override
Definition: Player.cpp:10828
SpellCooldowns GetSpellCooldowns() const
Definition: Player.h:2118
static uint8 GetAttackBySlot(uint8 slot)
Definition: PlayerStorage.cpp:573
ReputationRank GetReputationRank(uint32 faction_id) const
Definition: Player.cpp:5747
Unit * GetSelectedUnit() const
Definition: Player.cpp:11249
void RemoveSpellCooldown(uint32 spell_id, bool update=false)
Definition: Player.cpp:3454
void Say(std::string_view text, Language language, WorldObject const *=nullptr) override
Handles said message in regular chat based on declared language and in config pre-defined Range.
Definition: Player.cpp:9195
Item * GetItemByGuid(ObjectGuid guid) const
Definition: PlayerStorage.cpp:438
Spell * m_spellModTakingSpell
Definition: Player.h:2497
SpellInfo const * GetSpellInfo() const
Definition: Spell.h:574
uint8 GetRank() const
Definition: SpellInfo.cpp:2474
int32 GetMaxDuration() const
Definition: SpellInfo.cpp:2325
uint32 ProcChance
Definition: SpellInfo.h:354
uint32 GetCreatePowers(Powers power) const
Definition: Unit.cpp:15497
Aura * GetAura(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, ObjectGuid itemCasterGUID=ObjectGuid::Empty, uint8 reqEffMask=0) const
Definition: Unit.cpp:5487
void RemoveAurasWithMechanic(uint32 mechanic_mask, AuraRemoveMode removemode=AURA_REMOVE_BY_DEFAULT, uint32 except=0)
Definition: Unit.cpp:5161
int32 CalculateSpellDamage(Unit const *target, SpellInfo const *spellProto, uint8 effect_index, int32 const *basePoints=nullptr) const
Definition: Unit.cpp:14708
void SetCantProc(bool apply)
Definition: Unit.h:2316
bool HealthBelowPct(int32 pct) const
Definition: Unit.h:1442
void RemoveAurasDueToSpell(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, uint8 reqEffMask=0, AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT)
Definition: Unit.cpp:4823
int32 SpellBaseDamageBonusTaken(SpellSchoolMask schoolMask, bool isDoT=false)
Definition: Unit.cpp:11886
bool IsFriendlyTo(Unit const *unit) const
Definition: Unit.cpp:10202
int32 SpellBaseDamageBonusDone(SpellSchoolMask schoolMask)
Definition: Unit.cpp:11848
uint32 CountPctFromMaxHealth(int32 pct) const
Definition: Unit.h:1447
void CastDelayedSpellWithPeriodicAmount(Unit *caster, uint32 spellId, AuraType auraType, int32 addAmount, uint8 effectIndex=0)
Definition: Unit.cpp:20297
void RemoveMovementImpairingAuras(bool withRoot)
Definition: Unit.cpp:5137
bool IsEqual(uint32 p1=0, uint32 p2=0, uint32 p3=0) const
Definition: Util.h:458
Definition: SpellMgr.h:547
SpellInfo const * last
Definition: SpellMgr.h:551
uint8 rank
Definition: SpellMgr.h:552

◆ HandleEmoteCommand()

void Unit::HandleEmoteCommand ( uint32  emoteId)
1959{
1961 packet.EmoteID = emoteId;
1962 packet.Guid = GetGUID();
1963 SendMessageToSet(packet.Write(), true);
1964}
Definition: ChatPackets.h:29
WorldPacket const * Write() override
Definition: ChatPackets.cpp:20
uint32 EmoteID
Definition: ChatPackets.h:35
ObjectGuid Guid
Definition: ChatPackets.h:36

◆ HandleOverrideClassScriptAuraProc()

bool Unit::HandleOverrideClassScriptAuraProc ( Unit victim,
uint32  damage,
AuraEffect triggeredByAura,
SpellInfo const *  procSpell,
uint32  cooldown 
)
private
9823{
9824 int32 scriptId = triggeredByAura->GetMiscValue();
9825
9826 if (!victim || !victim->IsAlive())
9827 return false;
9828
9829 Item* castItem = triggeredByAura->GetBase()->GetCastItemGUID() && GetTypeId() == TYPEID_PLAYER
9830 ? ToPlayer()->GetItemByGuid(triggeredByAura->GetBase()->GetCastItemGUID()) : nullptr;
9831
9832 uint32 triggered_spell_id = 0;
9833
9834 switch (scriptId)
9835 {
9836 case 836: // Improved Blizzard (Rank 1)
9837 {
9838 if (!procSpell || procSpell->SpellVisual[0] != 9487)
9839 return false;
9840 triggered_spell_id = 12484;
9841 break;
9842 }
9843 case 988: // Improved Blizzard (Rank 2)
9844 {
9845 if (!procSpell || procSpell->SpellVisual[0] != 9487)
9846 return false;
9847 triggered_spell_id = 12485;
9848 break;
9849 }
9850 case 989: // Improved Blizzard (Rank 3)
9851 {
9852 if (!procSpell || procSpell->SpellVisual[0] != 9487)
9853 return false;
9854 triggered_spell_id = 12486;
9855 break;
9856 }
9857 case 4533: // Dreamwalker Raiment 2 pieces bonus
9858 {
9859 // Chance 50%
9860 if (!roll_chance_i(50))
9861 return false;
9862
9863 switch (victim->getPowerType())
9864 {
9865 case POWER_MANA:
9866 triggered_spell_id = 28722;
9867 break;
9868 case POWER_RAGE:
9869 triggered_spell_id = 28723;
9870 break;
9871 case POWER_ENERGY:
9872 triggered_spell_id = 28724;
9873 break;
9874 default:
9875 return false;
9876 }
9877 break;
9878 }
9879 case 4537: // Dreamwalker Raiment 6 pieces bonus
9880 triggered_spell_id = 28750; // Blessing of the Claw
9881 break;
9882 case 5497: // Improved Mana Gems
9883 triggered_spell_id = 37445; // Mana Surge
9884 break;
9885 case 7010: // Revitalize - can proc on full hp target
9886 case 7011:
9887 case 7012:
9888 {
9889 if (!roll_chance_i(triggeredByAura->GetAmount()))
9890 return false;
9891 switch (victim->getPowerType())
9892 {
9893 case POWER_MANA:
9894 triggered_spell_id = 48542;
9895 break;
9896 case POWER_RAGE:
9897 triggered_spell_id = 48541;
9898 break;
9899 case POWER_ENERGY:
9900 triggered_spell_id = 48540;
9901 break;
9902 case POWER_RUNIC_POWER:
9903 triggered_spell_id = 48543;
9904 break;
9905 default:
9906 break;
9907 }
9908 break;
9909 }
9910 default:
9911 break;
9912 }
9913
9914 // not processed
9915 if (!triggered_spell_id)
9916 return false;
9917
9918 // standard non-dummy case
9919 SpellInfo const* triggerEntry = sSpellMgr->GetSpellInfo(triggered_spell_id);
9920
9921 if (!triggerEntry)
9922 {
9923 LOG_ERROR("entities.unit", "Unit::HandleOverrideClassScriptAuraProc: Spell {} triggering for class script id {}", triggered_spell_id, scriptId);
9924 return false;
9925 }
9926
9927 if (cooldown)
9928 {
9929 if (HasSpellCooldown(triggered_spell_id))
9930 return false;
9931
9932 AddSpellCooldown(triggered_spell_id, 0, cooldown);
9933 }
9934
9935 CastSpell(victim, triggered_spell_id, true, castItem, triggeredByAura);
9936
9937 return true;
9938}

◆ HandleProcExtraAttackFor()

void Unit::HandleProcExtraAttackFor ( Unit victim,
uint32  count 
)
2707{
2708 while (count)
2709 {
2710 --count;
2711 AttackerStateUpdate(victim, BASE_ATTACK, true);
2712 }
2713}
void AttackerStateUpdate(Unit *victim, WeaponAttackType attType=BASE_ATTACK, bool extra=false, bool ignoreCasting=false)
Definition: Unit.cpp:2515

◆ HandleProcTriggerSpell()

bool Unit::HandleProcTriggerSpell ( Unit victim,
uint32  damage,
AuraEffect triggeredByAura,
SpellInfo const *  procSpell,
uint32  procFlag,
uint32  procEx,
uint32  cooldown,
uint32  procPhase,
ProcEventInfo eventInfo 
)
private
8874{
8875 // Get triggered aura spell info
8876 SpellInfo const* auraSpellInfo = triggeredByAura->GetSpellInfo();
8877
8878 // Basepoints of trigger aura
8879 int32 triggerAmount = triggeredByAura->GetAmount();
8880
8881 // Set trigger spell id, target, custom basepoints
8882 uint32 trigger_spell_id = auraSpellInfo->Effects[triggeredByAura->GetEffIndex()].TriggerSpell;
8883
8884 Unit* target = nullptr;
8885 int32 basepoints0 = 0;
8886
8887 if (triggeredByAura->GetAuraType() == SPELL_AURA_PROC_TRIGGER_SPELL_WITH_VALUE)
8888 basepoints0 = triggerAmount;
8889
8890 Item* castItem = triggeredByAura->GetBase()->GetCastItemGUID() && GetTypeId() == TYPEID_PLAYER
8891 ? ToPlayer()->GetItemByGuid(triggeredByAura->GetBase()->GetCastItemGUID()) : nullptr;
8892
8893 // Try handle unknown trigger spells
8894 //if (sSpellMgr->GetSpellInfo(trigger_spell_id) == nullptr)
8895 {
8896 switch (auraSpellInfo->SpellFamilyName)
8897 {
8899 switch (auraSpellInfo->Id)
8900 {
8901 case 43820: // Charm of the Witch Doctor (Amani Charm of the Witch Doctor trinket)
8902 // Pct value stored in dummy
8903 if (!victim)
8904 return false;
8905 basepoints0 = victim->GetCreateHealth() * auraSpellInfo->Effects[1].CalcValue() / 100;
8906 target = victim;
8907 break;
8908 case 57345: // Darkmoon Card: Greatness
8909 {
8910 float stat = 0.0f;
8911 // strength
8912 if (GetStat(STAT_STRENGTH) > stat) { trigger_spell_id = 60229; stat = GetStat(STAT_STRENGTH); }
8913 // agility
8914 if (GetStat(STAT_AGILITY) > stat) { trigger_spell_id = 60233; stat = GetStat(STAT_AGILITY); }
8915 // intellect
8916 if (GetStat(STAT_INTELLECT) > stat) { trigger_spell_id = 60234; stat = GetStat(STAT_INTELLECT);}
8917 // spirit
8918 if (GetStat(STAT_SPIRIT) > stat) { trigger_spell_id = 60235; }
8919 break;
8920 }
8921 case 67702: // Death's Choice, Item - Coliseum 25 Normal Melee Trinket
8922 {
8923 if (!damage)
8924 return false;
8925 float stat = 0.0f;
8926 // strength
8927 if (GetStat(STAT_STRENGTH) > stat) { trigger_spell_id = 67708; stat = GetStat(STAT_STRENGTH); }
8928 // agility
8929 if (GetStat(STAT_AGILITY) > stat) { trigger_spell_id = 67703; }
8930 break;
8931 }
8932 case 67771: // Death's Choice (heroic), Item - Coliseum 25 Heroic Melee Trinket
8933 {
8934 if (!damage)
8935 return false;
8936 float stat = 0.0f;
8937 // strength
8938 if (GetStat(STAT_STRENGTH) > stat) { trigger_spell_id = 67773; stat = GetStat(STAT_STRENGTH); }
8939 // agility
8940 if (GetStat(STAT_AGILITY) > stat) { trigger_spell_id = 67772; }
8941 break;
8942 }
8943 // Mana Drain Trigger
8944 case 27522:
8945 case 40336:
8946 {
8947 // On successful melee or ranged attack gain $29471s1 mana and if possible drain $27526s1 mana from the target.
8948 if (IsAlive())
8949 CastSpell(this, 29471, true, castItem, triggeredByAura);
8950 if (victim && victim->IsAlive())
8951 CastSpell(victim, 27526, true, castItem, triggeredByAura);
8952 return true;
8953 }
8954 // Forge of Souls, Devourer of Souls, Mirrored Soul
8955 case 69023:
8956 {
8957 int32 dmg = damage * 0.45f;
8958 if (dmg > 0)
8959 if (Aura* a = GetAura(69023))
8960 if (Unit* c = a->GetCaster())
8961 CastCustomSpell(c, 69034, &dmg, 0, 0, true);
8962 return true;
8963 }
8964 // Soul-Trader Beacon proc aura
8965 case 50051:
8966 {
8967 if (!victim)
8968 return false;
8969
8971 cr->CastSpell(victim, 50101, true);
8972
8973 return false;
8974 }
8975 }
8976 break;
8977 case SPELLFAMILY_MAGE:
8978 if (auraSpellInfo->SpellIconID == 2127) // Blazing Speed
8979 {
8980 switch (auraSpellInfo->Id)
8981 {
8982 case 31641: // Rank 1
8983 case 31642: // Rank 2
8984 trigger_spell_id = 31643;
8985 break;
8986 default:
8987 LOG_ERROR("entities.unit", "Unit::HandleProcTriggerSpell: Spell {} miss posibly Blazing Speed", auraSpellInfo->Id);
8988 return false;
8989 }
8990 }
8991 else if (auraSpellInfo->Id == 71761) // Deep Freeze Immunity State (only permanent)
8992 {
8993 Creature* creature = victim->ToCreature();
8994 if (!creature || !creature->HasMechanicTemplateImmunity(1 << (MECHANIC_STUN - 1)))
8995 return false;
8996 }
8997 break;
8999 {
9000 // Nether Protection
9001 if (auraSpellInfo->SpellIconID == 1985)
9002 {
9003 if (!procSpell)
9004 return false;
9005 switch (GetFirstSchoolInMask(procSpell->GetSchoolMask()))
9006 {
9008 return false; // ignore
9009 case SPELL_SCHOOL_HOLY:
9010 trigger_spell_id = 54370;
9011 break;
9012 case SPELL_SCHOOL_FIRE:
9013 trigger_spell_id = 54371;
9014 break;
9016 trigger_spell_id = 54375;
9017 break;
9018 case SPELL_SCHOOL_FROST:
9019 trigger_spell_id = 54372;
9020 break;
9022 trigger_spell_id = 54374;
9023 break;
9025 trigger_spell_id = 54373;
9026 break;
9027 default:
9028 return false;
9029 }
9030 }
9031 break;
9032 }
9033 case SPELLFAMILY_PRIEST:
9034 {
9035 // Blessed Recovery
9036 if (auraSpellInfo->SpellIconID == 1875)
9037 {
9038 switch (auraSpellInfo->Id)
9039 {
9040 case 27811:
9041 trigger_spell_id = 27813;
9042 break;
9043 case 27815:
9044 trigger_spell_id = 27817;
9045 break;
9046 case 27816:
9047 trigger_spell_id = 27818;
9048 break;
9049 default:
9050 LOG_ERROR("entities.unit", "Unit::HandleProcTriggerSpell: Spell {} not handled in BR", auraSpellInfo->Id);
9051 return false;
9052 }
9053 basepoints0 = CalculatePct(int32(damage), triggerAmount) / 3;
9054 target = this;
9055 // Add remaining ticks to healing done
9056 CastDelayedSpellWithPeriodicAmount(this, trigger_spell_id, SPELL_AURA_PERIODIC_HEAL, basepoints0);
9057 return true;
9058 }
9059 break;
9060 }
9061 case SPELLFAMILY_DRUID:
9062 {
9063 switch (auraSpellInfo->Id)
9064 {
9065 // Druid Forms Trinket
9066 case 37336:
9067 {
9068 switch (GetShapeshiftForm())
9069 {
9070 case FORM_NONE:
9071 trigger_spell_id = 37344;
9072 break;
9073 case FORM_CAT:
9074 trigger_spell_id = 37341;
9075 break;
9076 case FORM_BEAR:
9077 case FORM_DIREBEAR:
9078 trigger_spell_id = 37340;
9079 break;
9080 case FORM_TREE:
9081 trigger_spell_id = 37342;
9082 break;
9083 case FORM_MOONKIN:
9084 trigger_spell_id = 37343;
9085 break;
9086 default:
9087 return false;
9088 }
9089 break;
9090 }
9091 // Druid T9 Feral Relic (Lacerate, Swipe, Mangle, and Shred)
9092 case 67353:
9093 {
9094 switch (GetShapeshiftForm())
9095 {
9096 case FORM_CAT:
9097 trigger_spell_id = 67355;
9098 break;
9099 case FORM_BEAR:
9100 case FORM_DIREBEAR:
9101 trigger_spell_id = 67354;
9102 break;
9103 default:
9104 return false;
9105 }
9106 break;
9107 }
9108 default:
9109 break;
9110 }
9111 break;
9112 }
9113 case SPELLFAMILY_HUNTER:
9114 {
9115 if (auraSpellInfo->SpellIconID == 3247) // Piercing Shots
9116 {
9117 if (!victim)
9118 return false;
9119
9120 switch (auraSpellInfo->Id)
9121 {
9122 case 53234: // Rank 1
9123 case 53237: // Rank 2
9124 case 53238: // Rank 3
9125 trigger_spell_id = 63468;
9126 break;
9127 default:
9128 LOG_ERROR("entities.unit", "Unit::HandleProcTriggerSpell: Spell {} miss posibly Piercing Shots", auraSpellInfo->Id);
9129 return false;
9130 }
9131 SpellInfo const* TriggerPS = sSpellMgr->GetSpellInfo(trigger_spell_id);
9132 if (!TriggerPS)
9133 return false;
9134
9135 basepoints0 = CalculatePct(int32(damage), triggerAmount) / (TriggerPS->GetMaxDuration() / TriggerPS->Effects[0].Amplitude);
9136 victim->CastDelayedSpellWithPeriodicAmount(this, trigger_spell_id, SPELL_AURA_PERIODIC_DAMAGE, basepoints0);
9137 return true;
9138 }
9139 // Item - Hunter T9 4P Bonus (Steady Shot)
9140 else if (auraSpellInfo->Id == 67151)
9141 {
9142 if (GetTypeId() != TYPEID_PLAYER || !ToPlayer()->GetPet())
9143 return false;
9144
9145 target = ToPlayer()->GetPet();
9146 trigger_spell_id = 68130;
9147 break;
9148 }
9149 break;
9150 }
9152 {
9153 switch (auraSpellInfo->Id)
9154 {
9155 // Soul Preserver
9156 case 60510:
9157 {
9158 switch (getClass())
9159 {
9160 case CLASS_DRUID:
9161 trigger_spell_id = 60512;
9162 break;
9163 case CLASS_PALADIN:
9164 trigger_spell_id = 60513;
9165 break;
9166 case CLASS_PRIEST:
9167 trigger_spell_id = 60514;
9168 break;
9169 case CLASS_SHAMAN:
9170 trigger_spell_id = 60515;
9171 break;
9172 }
9173
9174 target = this;
9175 break;
9176 }
9177 case 37657: // Lightning Capacitor
9178 case 54841: // Thunder Capacitor
9179 case 67712: // Item - Coliseum 25 Normal Caster Trinket
9180 case 67758: // Item - Coliseum 25 Heroic Caster Trinket
9181 {
9182 if (!victim || !victim->IsAlive() || GetTypeId() != TYPEID_PLAYER)
9183 return false;
9184
9185 uint32 stack_spell_id = 0;
9186 switch (auraSpellInfo->Id)
9187 {
9188 case 37657:
9189 stack_spell_id = 37658;
9190 trigger_spell_id = 37661;
9191 break;
9192 case 54841:
9193 stack_spell_id = 54842;
9194 trigger_spell_id = 54843;
9195 break;
9196 case 67712:
9197 stack_spell_id = 67713;
9198 trigger_spell_id = 67714;
9199 break;
9200 case 67758:
9201 stack_spell_id = 67759;
9202 trigger_spell_id = 67760;
9203 break;
9204 }
9205
9206 if (cooldown && GetTypeId() == TYPEID_PLAYER)
9207 {
9208 if (ToPlayer()->HasSpellCooldown(stack_spell_id))
9209 return false;
9210
9211 ToPlayer()->AddSpellCooldown(stack_spell_id, 0, cooldown);
9212 }
9213
9214 CastSpell(this, stack_spell_id, true, nullptr, triggeredByAura);
9215
9216 Aura* dummy = GetAura(stack_spell_id);
9217 if (!dummy || dummy->GetStackAmount() < triggerAmount)
9218 return false;
9219
9220 RemoveAurasDueToSpell(stack_spell_id);
9221 CastSpell(victim, trigger_spell_id, true, nullptr, triggeredByAura);
9222 return true;
9223 }
9224 default:
9225 // Illumination
9226 if (auraSpellInfo->SpellIconID == 241)
9227 {
9228 if (!procSpell)
9229 return false;
9230 // procspell is triggered spell but we need mana cost of original casted spell
9231 uint32 originalSpellId = procSpell->Id;
9232 // Holy Shock heal
9233 if (procSpell->SpellFamilyFlags[1] & 0x00010000)
9234 {
9235 switch (procSpell->Id)
9236 {
9237 case 25914:
9238 originalSpellId = 20473;
9239 break;
9240 case 25913:
9241 originalSpellId = 20929;
9242 break;
9243 case 25903:
9244 originalSpellId = 20930;
9245 break;
9246 case 27175:
9247 originalSpellId = 27174;
9248 break;
9249 case 33074:
9250 originalSpellId = 33072;
9251 break;
9252 case 48820:
9253 originalSpellId = 48824;
9254 break;
9255 case 48821:
9256 originalSpellId = 48825;
9257 break;
9258 default:
9259 LOG_ERROR("entities.unit", "Unit::HandleProcTriggerSpell: Spell {} not handled in HShock", procSpell->Id);
9260 return false;
9261 }
9262 }
9263 SpellInfo const* originalSpell = sSpellMgr->GetSpellInfo(originalSpellId);
9264 if (!originalSpell)
9265 {
9266 LOG_ERROR("entities.unit", "Unit::HandleProcTriggerSpell: Spell {} unknown but selected as original in Illu", originalSpellId);
9267 return false;
9268 }
9269 // percent stored in effect 1 (class scripts) base points
9270 int32 cost = int32(originalSpell->ManaCost + CalculatePct(GetCreateMana(), originalSpell->ManaCostPercentage));
9271 basepoints0 = CalculatePct(cost, auraSpellInfo->Effects[1].CalcValue());
9272 trigger_spell_id = 20272;
9273 target = this;
9274 }
9275 break;
9276 }
9277 break;
9278 }
9279 case SPELLFAMILY_SHAMAN:
9280 {
9281 // Lightning Shield (overwrite non existing triggered spell call in spell.dbc
9282 if (auraSpellInfo->SpellFamilyFlags[0] & 0x400)
9283 {
9284 // Do not proc off from self-casted items
9285 if (Spell const* spell = eventInfo.GetProcSpell())
9286 {
9287 if (spell->m_castItemGUID && victim->GetGUID() == GetGUID())
9288 {
9289 return false;
9290 }
9291 }
9292
9293 trigger_spell_id = sSpellMgr->GetSpellWithRank(26364, auraSpellInfo->GetRank());
9294 }
9295 // Nature's Guardian
9296 else if (auraSpellInfo->SpellIconID == 2013)
9297 {
9298 // Check health condition - should drop to less 30% (damage deal after this!)
9299 if (!HealthBelowPctDamaged(30, damage))
9300 return false;
9301
9302 if (victim && victim->IsAlive())
9303 victim->GetThreatMgr().ModifyThreatByPercent(this, -10);
9304
9305 basepoints0 = int32(CountPctFromMaxHealth(triggerAmount));
9306 trigger_spell_id = 31616;
9307 target = this;
9308 }
9309 break;
9310 }
9312 {
9313 // Acclimation
9314 if (auraSpellInfo->SpellIconID == 1930)
9315 {
9316 if (!procSpell)
9317 return false;
9318 switch (GetFirstSchoolInMask(procSpell->GetSchoolMask()))
9319 {
9321 return false; // ignore
9322 case SPELL_SCHOOL_HOLY:
9323 trigger_spell_id = 50490;
9324 break;
9325 case SPELL_SCHOOL_FIRE:
9326 trigger_spell_id = 50362;
9327 break;
9329 trigger_spell_id = 50488;
9330 break;
9331 case SPELL_SCHOOL_FROST:
9332 trigger_spell_id = 50485;
9333 break;
9335 trigger_spell_id = 50489;
9336 break;
9338 trigger_spell_id = 50486;
9339 break;
9340 default:
9341 return false;
9342 }
9343 }
9344 // Blood Presence (Improved)
9345 else if (auraSpellInfo->Id == 63611)
9346 {
9347 if (GetTypeId() != TYPEID_PLAYER)
9348 return false;
9349
9350 trigger_spell_id = 50475;
9351 basepoints0 = CalculatePct(int32(damage), triggerAmount);
9352 }
9353 break;
9354 }
9355 }
9356 }
9357
9358 // All ok. Check current trigger spell
9359 SpellInfo const* triggerEntry = sSpellMgr->GetSpellInfo(trigger_spell_id);
9360 if (!triggerEntry)
9361 {
9362 // Don't cast unknown spell
9363 LOG_ERROR("entities.unit", "Unit::HandleProcTriggerSpell: Spell {} (effIndex: {}) has unknown TriggerSpell {}. Unhandled custom case?", auraSpellInfo->Id, triggeredByAura->GetEffIndex(), trigger_spell_id);
9364 return false;
9365 }
9366
9367 // not allow proc extra attack spell at extra attack
9368 if (triggerEntry->HasEffect(SPELL_EFFECT_ADD_EXTRA_ATTACKS))
9369 {
9370 uint32 lastExtraAttackSpell = eventInfo.GetActor()->GetLastExtraAttackSpell();
9371
9372 // Patch 1.12.0(?) extra attack abilities can no longer chain proc themselves
9373 if (lastExtraAttackSpell == trigger_spell_id)
9374 {
9375 return false;
9376 }
9377
9378 // Patch 2.2.0 Sword Specialization (Warrior, Rogue) extra attack can no longer proc additional extra attacks
9379 // 3.3.5 Sword Specialization (Warrior), Hack and Slash (Rogue)
9380 if (lastExtraAttackSpell == SPELL_SWORD_SPECIALIZATION || lastExtraAttackSpell == SPELL_HACK_AND_SLASH)
9381 {
9382 return false;
9383 }
9384 }
9385
9386 // Custom requirements (not listed in procEx) Warning! damage dealing after this
9387 // Custom triggered spells
9388 switch (auraSpellInfo->Id)
9389 {
9390 // Deep Wounds
9391 case 12834:
9392 case 12849:
9393 case 12867:
9394 {
9395 if (GetTypeId() != TYPEID_PLAYER)
9396 return false;
9397
9398 if (procFlags & PROC_FLAG_DONE_OFFHAND_ATTACK)
9400 else
9402 break;
9403 }
9404 // Persistent Shield (Scarab Brooch trinket)
9405 // This spell originally trigger 13567 - Dummy Trigger (vs dummy efect)
9406 case 26467:
9407 {
9408 basepoints0 = int32(CalculatePct(damage, 15));
9409 target = victim;
9410 trigger_spell_id = 26470;
9411 break;
9412 }
9413 // Unyielding Knights (item exploit 29108\29109)
9414 case 38164:
9415 {
9416 if (!victim || victim->GetEntry() != 19457) // Proc only if your target is Grillok
9417 return false;
9418 break;
9419 }
9420 // Deflection
9421 case 52420:
9422 {
9423 if (!HealthBelowPct(35))
9424 return false;
9425 break;
9426 }
9427
9428 // Cheat Death
9429 case 28845:
9430 {
9431 // When your health drops below 20%
9432 if (HealthBelowPctDamaged(20, damage) || HealthBelowPct(20))
9433 return false;
9434 break;
9435 }
9436 // Deadly Swiftness (Rank 1)
9437 case 31255:
9438 {
9439 // whenever you deal damage to a target who is below 20% health.
9440 if (!victim || !victim->IsAlive() || victim->HealthAbovePct(20))
9441 return false;
9442
9443 target = this;
9444 trigger_spell_id = 22588;
9445 [[fallthrough]]; // TODO: Not sure whether the fallthrough was a mistake (forgetting a break) or intended. This should be double-checked.
9446 }
9447 // Bonus Healing (Crystal Spire of Karabor mace)
9448 case 40971:
9449 {
9450 // If your target is below $s1% health
9451 if (!victim || !victim->IsAlive() || victim->HealthAbovePct(triggerAmount))
9452 return false;
9453 break;
9454 }
9455 // Rapid Recuperation
9456 case 53228:
9457 case 53232:
9458 {
9459 // This effect only from Rapid Fire (ability cast)
9460 if (!procSpell || !(procSpell->SpellFamilyFlags[0] & 0x20))
9461 return false;
9462 break;
9463 }
9464 // Decimation
9465 case 63156:
9466 case 63158:
9467 // Can proc only if target has hp below 35%
9468 if (!victim || !victim->HasAuraState(AURA_STATE_HEALTHLESS_35_PERCENT, procSpell, this))
9469 return false;
9470 break;
9471 // Ulduar, Hodir, Toasty Fire
9472 case 62821:
9473 if (this->GetTypeId() != TYPEID_PLAYER) // spell has Attribute, but persistent area auras ignore it
9474 return false;
9475 break;
9476 case 15337: // Improved Spirit Tap (Rank 1)
9477 case 15338: // Improved Spirit Tap (Rank 2)
9478 {
9479 if (!procSpell)
9480 return false;
9481
9482 if (procSpell->SpellFamilyFlags[0] & 0x800000)
9483 if ((procSpell->Id != 58381) || !roll_chance_i(50))
9484 return false;
9485
9486 target = victim;
9487 break;
9488 }
9489 // Professor Putricide - Ooze Spell Tank Protection
9490 case 71770:
9491 if (victim)
9492 victim->CastSpell(victim, trigger_spell_id, true); // EffectImplicitTarget is self
9493 return true;
9494 case 45057: // Evasive Maneuvers (Commendation of Kael`thas trinket)
9495 case 71634: // Item - Icecrown 25 Normal Tank Trinket 1
9496 case 71640: // Item - Icecrown 25 Heroic Tank Trinket 1
9497 case 75475: // Item - Chamber of Aspects 25 Normal Tank Trinket
9498 case 75481: // Item - Chamber of Aspects 25 Heroic Tank Trinket
9499 {
9500 // Procs only if damage takes health below $s1%
9501 if (!HealthBelowPctDamaged(triggerAmount, damage))
9502 return false;
9503 break;
9504 }
9505 default:
9506 break;
9507 }
9508
9509 if (auraSpellInfo->SpellFamilyName == SPELLFAMILY_DEATHKNIGHT)
9510 {
9511 // Xinef: keep this order, Aura 70656 has SpellIconID 85!
9512 // Item - Death Knight T10 Melee 4P Bonus
9513 if (auraSpellInfo->Id == 70656)
9514 {
9516 return false;
9517
9518 for (uint8 i = 0; i < MAX_RUNES; ++i)
9519 if (ToPlayer()->GetRuneCooldown(i) == 0)
9520 return false;
9521 }
9522 // Blade Barrier
9523 else if (auraSpellInfo->SpellIconID == 85)
9524 {
9525 Player* plr = ToPlayer();
9526 if (!plr || plr->getClass() != CLASS_DEATH_KNIGHT || !procSpell)
9527 return false;
9528
9530 return false;
9531 }
9532 // Rime
9533 else if (auraSpellInfo->SpellIconID == 56)
9534 {
9535 if (GetTypeId() != TYPEID_PLAYER)
9536 return false;
9537
9538 // Howling Blast
9540 }
9541 }
9542
9543 // Custom basepoints/target for exist spell
9544 // dummy basepoints or other customs
9545 switch (trigger_spell_id)
9546 {
9547 // Auras which should proc on area aura source (caster in this case):
9548 // Turn the Tables
9549 case 52914:
9550 case 52915:
9551 case 52910:
9552 // Honor Among Thieves
9553 case 51699:
9554 {
9555 target = triggeredByAura->GetBase()->GetCaster();
9556 if (!target)
9557 return false;
9558
9559 if (Player* pTarget = target->ToPlayer())
9560 {
9561 if (cooldown)
9562 {
9563 if (pTarget->HasSpellCooldown(trigger_spell_id) )
9564 return false;
9565 pTarget->AddSpellCooldown(trigger_spell_id, 0, cooldown);
9566 }
9567
9568 Unit* cptarget = nullptr;
9569 if (trigger_spell_id == 51699)
9570 {
9571 cptarget = pTarget->GetComboTarget();
9572 if (!cptarget)
9573 {
9574 cptarget = pTarget->GetSelectedUnit();
9575 }
9576 }
9577 else
9578 cptarget = target;
9579
9580 if (cptarget)
9581 {
9582 target->CastSpell(cptarget, trigger_spell_id, true);
9583 return true;
9584 }
9585 }
9586 return false;
9587 }
9588 // Cast positive spell on enemy target
9589 case 7099: // Curse of Mending
9590 case 39703: // Curse of Mending
9591 case 29494: // Temptation
9592 case 20233: // Improved Lay on Hands (cast on target)
9593 {
9594 target = victim;
9595 break;
9596 }
9597 // Ruby Drake, Evasive Aura
9598 case 50241:
9599 {
9600 if( GetAura(50240) )
9601 return false;
9602
9603 break;
9604 }
9605 // Combo points add triggers (need add combopoint only for main target, and after possible combopoints reset)
9606 case 15250: // Rogue Setup
9607 {
9608 // applied only for main target
9609 if (!victim || (GetTypeId() == TYPEID_PLAYER && victim != ToPlayer()->GetSelectedUnit()))
9610 return false;
9611 break; // continue normal case
9612 }
9613 // Finish movies that add combo
9614 case 14189: // Seal Fate (Netherblade set)
9615 case 14157: // Ruthlessness
9616 {
9617 victim = nullptr;
9618 // Need add combopoint AFTER finish movie (or they dropped in finish phase)
9619 break;
9620 }
9621 // Item - Druid T10 Balance 2P Bonus
9622 case 16870:
9623 {
9624 if (HasAura(70718))
9625 CastSpell(this, 70721, true);
9626 RemoveAurasDueToSpell(trigger_spell_id);
9627 break;
9628 }
9629 // Shamanistic Rage triggered spell
9630 case 30824:
9631 {
9632 basepoints0 = int32(CalculatePct(GetTotalAttackPowerValue(BASE_ATTACK), triggerAmount));
9633 break;
9634 }
9635 // Enlightenment (trigger only from mana cost spells)
9636 case 35095:
9637 {
9638 if (!procSpell || procSpell->PowerType != POWER_MANA || (procSpell->ManaCost == 0 && procSpell->ManaCostPercentage == 0 && procSpell->ManaCostPerlevel == 0))
9639 return false;
9640 break;
9641 }
9642 // Demonic Pact
9643 case 48090:
9644 {
9645 // Get talent aura from owner
9646 if (IsPet())
9647 if (Unit* owner = GetOwner())
9648 {
9649 if (HasSpellCooldown(trigger_spell_id))
9650 return false;
9651 AddSpellCooldown(trigger_spell_id, 0, cooldown);
9652
9653 if (AuraEffect* aurEff = owner->GetDummyAuraEffect(SPELLFAMILY_WARLOCK, 3220, 0))
9654 {
9655 int32 spellPower = owner->SpellBaseDamageBonusDone(SpellSchoolMask(SPELL_SCHOOL_MASK_MAGIC));
9656 if (AuraEffect const* demonicAuraEffect = GetAuraEffect(trigger_spell_id, EFFECT_0))
9657 spellPower -= demonicAuraEffect->GetAmount();
9658
9659 basepoints0 = int32((aurEff->GetAmount() * spellPower + 100.0f) / 100.0f);
9660 CastCustomSpell(this, trigger_spell_id, &basepoints0, &basepoints0, nullptr, true, castItem, triggeredByAura);
9661 return true;
9662 }
9663 }
9664 break;
9665 }
9666 case 46916: // Slam! (Bloodsurge proc)
9667 case 52437: // Sudden Death
9668 {
9669 // Item - Warrior T10 Melee 4P Bonus
9670 if (AuraEffect const* aurEff = GetAuraEffect(70847, 0))
9671 {
9672 if (!roll_chance_i(aurEff->GetAmount()))
9673 {
9674 // Xinef: dont allow normal proc to override set one
9675 if (GetAura((trigger_spell_id == 46916) ? 71072 : 71069))
9676 return false;
9677 // Xinef: just to be sure
9678 RemoveAurasDueToSpell(70849);
9679 break;
9680 }
9681
9682 // Xinef: fully remove all auras and reapply once more
9683 RemoveAurasDueToSpell(70849);
9684 RemoveAurasDueToSpell(71072);
9685 RemoveAurasDueToSpell(71069);
9686
9687 CastSpell(this, 70849, true, castItem, triggeredByAura); // Extra Charge!
9688 if (trigger_spell_id == 46916)
9689 CastSpell(this, 71072, true, castItem, triggeredByAura); // Slam GCD Reduced
9690 else
9691 CastSpell(this, 71069, true, castItem, triggeredByAura); // Execute GCD Reduced
9692 }
9693 break;
9694 }
9695 // Sword and Board
9696 case 50227:
9697 {
9698 // Remove cooldown on Shield Slam
9699 if (GetTypeId() == TYPEID_PLAYER)
9701 break;
9702 }
9703 // Maelstrom Weapon
9704 case 53817:
9705 {
9706 // have rank dependent proc chance, ignore too often cases
9707 // PPM = 2.5 * (rank of talent),
9708 uint32 rank = auraSpellInfo->GetRank();
9709 // 5 rank -> 100% 4 rank -> 80% and etc from full rate
9710 if (!roll_chance_i(20 * rank))
9711 return false;
9712
9713 // Item - Shaman T10 Enhancement 4P Bonus
9714 if (AuraEffect const* aurEff = GetAuraEffect(70832, 0))
9715 if (Aura const* maelstrom = GetAura(53817))
9716 // xinef: we have 4 charges and all proc conditions are met - aura reaches 5 charges
9717 if ((maelstrom->GetStackAmount() == 4) && roll_chance_i(aurEff->GetAmount()))
9718 CastSpell(this, 70831, true, castItem, triggeredByAura);
9719
9720 break;
9721 }
9722 // Astral Shift
9723 case 52179:
9724 {
9725 if (!procSpell || !(procEx & (PROC_EX_NORMAL_HIT | PROC_EX_CRITICAL_HIT)) || this == victim)
9726 return false;
9727
9728 // Need stun, fear or silence mechanic
9729 if (!(procSpell->GetAllEffectsMechanicMask() & ((1 << MECHANIC_SILENCE) | (1 << MECHANIC_STUN) | (1 << MECHANIC_FEAR))))
9730 return false;
9731 break;
9732 }
9733 // Glyph of Death's Embrace
9734 case 58679:
9735 {
9736 // Proc only from healing part of Death Coil. Check is essential as all Death Coil spells have 0x2000 mask in SpellFamilyFlags
9737 if (!procSpell || !(procSpell->SpellFamilyName == SPELLFAMILY_DEATHKNIGHT && procSpell->SpellFamilyFlags[0] == 0x80002000))
9738 return false;
9739 break;
9740 }
9741 // Glyph of Death Grip
9742 case 58628:
9743 {
9744 // remove cooldown of Death Grip
9745 if (GetTypeId() == TYPEID_PLAYER)
9746 ToPlayer()->RemoveSpellCooldown(49576, true);
9747 return true;
9748 }
9749 // Savage Defense
9750 case 62606:
9751 {
9752 basepoints0 = CalculatePct(triggerAmount, GetTotalAttackPowerValue(BASE_ATTACK));
9753 break;
9754 }
9755 // Body and Soul
9756 case 64128:
9757 case 65081:
9758 {
9759 // Proc only from PW:S cast
9760 if (!procSpell || !(procSpell->SpellFamilyFlags[0] & 0x00000001))
9761 return false;
9762 break;
9763 }
9764 // Culling the Herd
9765 case 70893:
9766 {
9767 if (!procSpell)
9768 {
9769 return false;
9770 }
9771 // check if we're doing a critical hit
9772 if (!(procSpell->SpellFamilyFlags[1] & 0x10000000) && (procEx != PROC_EX_CRITICAL_HIT))
9773 return false;
9774 // check if we're procced by Claw, Bite or Smack (need to use the spell icon ID to detect it)
9775 if (!(procSpell->SpellIconID == 262 || procSpell->SpellIconID == 1680 || procSpell->SpellIconID == 473))
9776 return false;
9777 break;
9778 }
9779 // Fingers of Frost, synchronise with Frostbite
9780 case 44544:
9781 {
9782 if (procPhase == PROC_SPELL_PHASE_HIT)
9783 {
9784 // Find Frostbite
9786 {
9787 if (!victim)
9788 return false;
9789
9790 uint8 fofRank = sSpellMgr->GetSpellRank(triggeredByAura->GetId());
9791 uint8 fbRank = sSpellMgr->GetSpellRank(aurEff->GetId());
9792 uint8 chance = uint8(std::ceil(fofRank * fbRank * 16.6f));
9793
9794 if (roll_chance_i(chance))
9795 CastSpell(victim, aurEff->GetSpellInfo()->Effects[EFFECT_0].TriggerSpell, true);
9796 }
9797 }
9798 break;
9799 }
9800 }
9801
9802 // try detect target manually if not set
9803 if (!target)
9804 target = !(procFlags & (PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_POS | PROC_FLAG_DONE_SPELL_NONE_DMG_CLASS_POS)) && triggerEntry->IsPositive() ? this : victim;
9805
9806 if (cooldown)
9807 {
9808 if (HasSpellCooldown(triggerEntry->Id))
9809 return false;
9810
9811 AddSpellCooldown(triggerEntry->Id, 0, cooldown);
9812 }
9813
9814 if(basepoints0)
9815 CastCustomSpell(target, triggerEntry->Id, &basepoints0, nullptr, nullptr, true, castItem, triggeredByAura);
9816 else
9817 CastSpell(target, triggerEntry->Id, true, castItem, triggeredByAura);
9818
9819 return true;
9820}
@ SPELL_EFFECT_ADD_EXTRA_ATTACKS
Definition: SharedDefines.h:769
@ MECHANIC_FEAR
Definition: SharedDefines.h:1302
@ MECHANIC_SILENCE
Definition: SharedDefines.h:1306
@ AURA_STATE_HEALTHLESS_35_PERCENT
Definition: SharedDefines.h:1277
@ SPELL_SCHOOL_MASK_MAGIC
Definition: SharedDefines.h:284
@ SPELL_AURA_PROC_TRIGGER_SPELL_WITH_VALUE
Definition: SpellAuraDefines.h:294
@ SPELL_AURA_ADD_TARGET_TRIGGER
Definition: SpellAuraDefines.h:172
@ PROC_SPELL_PHASE_HIT
Definition: SpellMgr.h:244
#define SUMMON_SLOT_MINIPET
Definition: Unit.h:1213
@ FORM_MOONKIN
Definition: Unit.h:119
@ FORM_NONE
Definition: Unit.h:90
@ FORM_TREE
Definition: Unit.h:92
@ SPELL_HACK_AND_SLASH
Definition: Unit.h:723
@ SPELL_SWORD_SPECIALIZATION
Definition: Unit.h:722
bool HasMechanicTemplateImmunity(uint32 mask) const
Definition: Creature.cpp:2128
bool IsBaseRuneSlotsOnCooldown(RuneType runeType) const
Definition: Player.cpp:13184
void RemoveCategoryCooldown(uint32 cat)
Definition: Player.cpp:3462
Spell const * GetProcSpell() const
Definition: Unit.h:867
Unit * GetActor()
Definition: Unit.h:858
uint32 ManaCostPercentage
Definition: SpellInfo.h:365
bool HasEffect(SpellEffects effect) const
Definition: SpellInfo.cpp:868
uint32 ManaCost
Definition: SpellInfo.h:361
void ModifyThreatByPercent(Unit *victim, int32 percent)
Definition: ThreatMgr.cpp:493
bool HealthAbovePct(int32 pct) const
Definition: Unit.h:1444
float GetTotalAttackPowerValue(WeaponAttackType attType, Unit *pVictim=nullptr) const
Definition: Unit.cpp:15285
uint32 GetLastExtraAttackSpell() const
Definition: Unit.h:1567
uint32 GetCreateHealth() const
Definition: Unit.h:2036
Unit * GetComboTarget() const
Definition: Unit.h:2287
bool HealthBelowPctDamaged(int32 pct, uint32 damage) const
Definition: Unit.h:1443
Creature * GetCreature(WorldObject const &u, ObjectGuid const guid)
Definition: ObjectAccessor.cpp:215

◆ HandleSafeUnitPointersOnDelete()

void Unit::HandleSafeUnitPointersOnDelete ( Unit thisUnit)
static
4258{
4259 if (thisUnit->SafeUnitPointerSet.empty())
4260 return;
4261 for (std::set<SafeUnitPointer*>::iterator itr = thisUnit->SafeUnitPointerSet.begin(); itr != thisUnit->SafeUnitPointerSet.end(); ++itr)
4262 (*itr)->UnitDeleted();
4263
4264 thisUnit->SafeUnitPointerSet.clear();
4265}

◆ HandleSpellClick()

bool Unit::HandleSpellClick ( Unit clicker,
int8  seatId = -1 
)

First check simple relations from clicker to clickee

Check database conditions

19567{
19568 Creature* creature = ToCreature();
19569 if (creature && creature->IsAIEnabled)
19570 {
19571 if (!creature->AI()->BeforeSpellClick(clicker))
19572 {
19573 return false;
19574 }
19575 }
19576
19577 bool result = false;
19578 uint32 spellClickEntry = GetVehicleKit() ? GetVehicleKit()->GetCreatureEntry() : GetEntry();
19579 SpellClickInfoMapBounds clickPair = sObjectMgr->GetSpellClickInfoMapBounds(spellClickEntry);
19580 for (SpellClickInfoContainer::const_iterator itr = clickPair.first; itr != clickPair.second; ++itr)
19581 {
19583 if (!itr->second.IsFitToRequirements(clicker, this))
19584 continue;
19585
19587 ConditionList conds = sConditionMgr->GetConditionsForSpellClickEvent(spellClickEntry, itr->second.spellId);
19588 ConditionSourceInfo info = ConditionSourceInfo(clicker, this);
19589 if (!sConditionMgr->IsObjectMeetToConditions(info, conds))
19590 continue;
19591
19592 Unit* caster = (itr->second.castFlags & NPC_CLICK_CAST_CASTER_CLICKER) ? clicker : this;
19593 Unit* target = (itr->second.castFlags & NPC_CLICK_CAST_TARGET_CLICKER) ? clicker : this;
19594 ObjectGuid origCasterGUID = (itr->second.castFlags & NPC_CLICK_CAST_ORIG_CASTER_OWNER) ? GetOwnerGUID() : clicker->GetGUID();
19595
19596 SpellInfo const* spellEntry = sSpellMgr->GetSpellInfo(itr->second.spellId);
19597
19598 // xinef: dont allow players to enter vehicles on arena
19599 if (spellEntry->HasAura(SPELL_AURA_CONTROL_VEHICLE) && caster->GetTypeId() == TYPEID_PLAYER && caster->FindMap() && caster->FindMap()->IsBattleArena())
19600 continue;
19601
19602 if (seatId > -1)
19603 {
19604 uint8 i = 0;
19605 bool valid = false;
19606 while (i < MAX_SPELL_EFFECTS)
19607 {
19608 if (spellEntry->Effects[i].ApplyAuraName == SPELL_AURA_CONTROL_VEHICLE)
19609 {
19610 valid = true;
19611 break;
19612 }
19613 ++i;
19614 }
19615
19616 if (!valid)
19617 {
19618 LOG_ERROR("sql.sql", "Spell {} specified in npc_spellclick_spells is not a valid vehicle enter aura!", itr->second.spellId);
19619 continue;
19620 }
19621
19622 if (IsInMap(caster))
19623 caster->CastCustomSpell(itr->second.spellId, SpellValueMod(SPELLVALUE_BASE_POINT0 + i), seatId + 1, target, GetVehicleKit() ? TRIGGERED_IGNORE_CASTER_MOUNTED_OR_ON_VEHICLE : TRIGGERED_NONE, nullptr, nullptr, origCasterGUID);
19624 else // This can happen during Player::_LoadAuras
19625 {
19627 for (uint32 j = 0; j < MAX_SPELL_EFFECTS; ++j)
19628 bp0[j] = spellEntry->Effects[j].BasePoints;
19629
19630 bp0[i] = seatId;
19631 Aura::TryRefreshStackOrCreate(spellEntry, MAX_EFFECT_MASK, this, clicker, bp0, nullptr, origCasterGUID);
19632 }
19633 }
19634 else
19635 {
19636 if (IsInMap(caster))
19637 caster->CastSpell(target, spellEntry, GetVehicleKit() ? TRIGGERED_IGNORE_CASTER_MOUNTED_OR_ON_VEHICLE : TRIGGERED_NONE, nullptr, nullptr, origCasterGUID);
19638 else
19639 Aura::TryRefreshStackOrCreate(spellEntry, MAX_EFFECT_MASK, this, clicker, nullptr, nullptr, origCasterGUID);
19640 }
19641
19642 result = true;
19643 }
19644
19645 if (creature && creature->IsAIEnabled)
19646 creature->AI()->OnSpellClick(clicker, result);
19647
19648 return result;
19649}
#define sConditionMgr
Definition: ConditionMgr.h:289
std::list< Condition * > ConditionList
Definition: ConditionMgr.h:236
std::pair< SpellClickInfoContainer::const_iterator, SpellClickInfoContainer::const_iterator > SpellClickInfoMapBounds
Definition: ObjectMgr.h:409
@ NPC_CLICK_CAST_TARGET_CLICKER
Definition: SharedDefines.h:663
@ NPC_CLICK_CAST_ORIG_CASTER_OWNER
Definition: SharedDefines.h:664
@ NPC_CLICK_CAST_CASTER_CLICKER
Definition: SharedDefines.h:662
SpellValueMod
Definition: SpellDefines.h:113
virtual void OnSpellClick(Unit *, bool &)
Definition: CreatureAI.h:195
virtual bool BeforeSpellClick(Unit *)
Definition: CreatureAI.h:193
bool HasAura(AuraType aura) const
Definition: SpellInfo.cpp:876
uint32 GetCreatureEntry() const
Definition: Vehicle.h:41
Definition: ConditionMgr.h:181

◆ HandleStatModifier()

bool Unit::HandleStatModifier ( UnitMods  unitMod,
UnitModifierType  modifierType,
float  amount,
bool  apply 
)
15061{
15062 if (unitMod >= UNIT_MOD_END || modifierType >= MODIFIER_TYPE_END)
15063 {
15064 LOG_ERROR("entities.unit", "ERROR in HandleStatModifier(): non-existing UnitMods or wrong UnitModifierType!");
15065 return false;
15066 }
15067
15068 switch (modifierType)
15069 {
15070 case BASE_VALUE:
15071 case TOTAL_VALUE:
15072 m_auraModifiersGroup[unitMod][modifierType] += apply ? amount : -amount;
15073 break;
15074 case BASE_PCT:
15075 case TOTAL_PCT:
15076 ApplyPercentModFloatVar(m_auraModifiersGroup[unitMod][modifierType], amount, apply);
15077 break;
15078 default:
15079 break;
15080 }
15081
15082 if (!CanModifyStats())
15083 return false;
15084
15085 switch (unitMod)
15086 {
15093 break;
15094
15095 case UNIT_MOD_ARMOR:
15096 UpdateArmor();
15097 break;
15098 case UNIT_MOD_HEALTH:
15100 break;
15101
15102 case UNIT_MOD_MANA:
15103 case UNIT_MOD_RAGE:
15104 case UNIT_MOD_FOCUS:
15105 case UNIT_MOD_ENERGY:
15106 case UNIT_MOD_HAPPINESS:
15107 case UNIT_MOD_RUNE:
15110 break;
15111
15119 break;
15120
15123 break;
15126 break;
15127
15130 break;
15133 break;
15136 break;
15137
15138 default:
15139 break;
15140 }
15141
15142 return true;
15143}
@ UNIT_MOD_ARMOR
Definition: Unit.h:275
@ UNIT_MOD_ATTACK_POWER
Definition: Unit.h:282
@ UNIT_MOD_HEALTH
Definition: Unit.h:267
@ UNIT_MOD_DAMAGE_RANGED
Definition: Unit.h:286
@ UNIT_MOD_DAMAGE_MAINHAND
Definition: Unit.h:284
@ UNIT_MOD_ATTACK_POWER_RANGED
Definition: Unit.h:283
SpellSchools GetSpellSchoolByAuraGroup(UnitMods unitMod) const
Definition: Unit.cpp:15202
Stats GetStatByAuraGroup(UnitMods unitMod) const
Definition: Unit.cpp:15234
virtual void UpdateAttackPowerAndDamage(bool ranged=false)=0
virtual void UpdateResistances(uint32 school)=0
Powers GetPowerTypeByAuraGroup(UnitMods unitMod) const
Definition: Unit.cpp:15263
virtual void UpdateDamagePhysical(WeaponAttackType attType)
Definition: StatSystem.cpp:60
virtual void UpdateArmor()=0
virtual void UpdateMaxPower(Powers power)=0
virtual bool UpdateStats(Stats stat)=0
bool CanModifyStats() const
Definition: Unit.h:2102
virtual void UpdateMaxHealth()=0
void apply(T *val)
Definition: ByteConverter.h:40

◆ HasAura()

bool Unit::HasAura ( uint32  spellId,
ObjectGuid  casterGUID = ObjectGuid::Empty,
ObjectGuid  itemCasterGUID = ObjectGuid::Empty,
uint8  reqEffMask = 0 
) const
5599{
5600 if (GetAuraApplication(spellId, casterGUID, itemCasterGUID, reqEffMask))
5601 return true;
5602 return false;
5603}

◆ HasAuraEffect()

bool Unit::HasAuraEffect ( uint32  spellId,
uint8  effIndex,
ObjectGuid  caster = ObjectGuid::Empty 
) const
5569{
5570 AuraApplicationMapBounds range = m_appliedAuras.equal_range(spellId);
5571 for (AuraApplicationMap::const_iterator itr = range.first; itr != range.second; ++itr)
5572 {
5573 if (itr->second->HasEffect(effIndex)
5574 && (!caster || itr->second->GetBase()->GetCasterGUID() == caster))
5575 {
5576 return true;
5577 }
5578 }
5579 return false;
5580}

◆ HasAuraState()

bool Unit::HasAuraState ( AuraStateType  flag,
SpellInfo const *  spellProto = nullptr,
Unit const *  Caster = nullptr 
) const
10496{
10497 if (Caster)
10498 {
10499 if (spellProto)
10500 {
10501 AuraEffectList const& stateAuras = Caster->GetAuraEffectsByType(SPELL_AURA_ABILITY_IGNORE_AURASTATE);
10502 for (AuraEffectList::const_iterator j = stateAuras.begin(); j != stateAuras.end(); ++j)
10503 if ((*j)->IsAffectedOnSpell(spellProto))
10504 return true;
10505 }
10506 // Check per caster aura state
10507 // If aura with aurastate by caster not found return false
10508 if ((1 << (flag - 1)) & PER_CASTER_AURA_STATE_MASK)
10509 {
10510 AuraStateAurasMapBounds range = m_auraStateAuras.equal_range(flag);
10511 for (AuraStateAurasMap::const_iterator itr = range.first; itr != range.second; ++itr)
10512 if (itr->second->GetBase()->GetCasterGUID() == Caster->GetGUID())
10513 return true;
10514 return false;
10515 }
10516 }
10517
10518 return HasFlag(UNIT_FIELD_AURASTATE, 1 << (flag - 1));
10519}
@ SPELL_AURA_ABILITY_IGNORE_AURASTATE
Definition: SpellAuraDefines.h:325
std::pair< AuraStateAurasMap::const_iterator, AuraStateAurasMap::const_iterator > AuraStateAurasMapBounds
Definition: Unit.h:1304

◆ HasAuraType()

bool Unit::HasAuraType ( AuraType  auraType) const
5606{
5607 return (!m_modAuras[auraType].empty());
5608}

◆ HasAuraTypeWithAffectMask()

bool Unit::HasAuraTypeWithAffectMask ( AuraType  auratype,
SpellInfo const *  affectedSpell 
) const
5639{
5640 AuraEffectList const& mTotalAuraList = GetAuraEffectsByType(auratype);
5641 for (AuraEffectList::const_iterator i = mTotalAuraList.begin(); i != mTotalAuraList.end(); ++i)
5642 if ((*i)->IsAffectedOnSpell(affectedSpell))
5643 return true;
5644 return false;
5645}

◆ HasAuraTypeWithCaster()

bool Unit::HasAuraTypeWithCaster ( AuraType  auratype,
ObjectGuid  caster 
) const
5611{
5612 AuraEffectList const& mTotalAuraList = GetAuraEffectsByType(auratype);
5613 for (AuraEffectList::const_iterator i = mTotalAuraList.begin(); i != mTotalAuraList.end(); ++i)
5614 if (caster == (*i)->GetCasterGUID())
5615 return true;
5616 return false;
5617}

◆ HasAuraTypeWithFamilyFlags()

bool Unit::HasAuraTypeWithFamilyFlags ( AuraType  auraType,
uint32  familyName,
uint32  familyFlags 
) const
770{
771 if (!HasAuraType(auraType))
772 return false;
773 AuraEffectList const& auras = GetAuraEffectsByType(auraType);
774 for (AuraEffectList::const_iterator itr = auras.begin(); itr != auras.end(); ++itr)
775 if (SpellInfo const* iterSpellProto = (*itr)->GetSpellInfo())
776 if (iterSpellProto->SpellFamilyName == familyName && iterSpellProto->SpellFamilyFlags[0] & familyFlags)
777 return true;
778 return false;
779}

◆ HasAuraTypeWithMiscvalue()

bool Unit::HasAuraTypeWithMiscvalue ( AuraType  auratype,
int32  miscvalue 
) const
5630{
5631 AuraEffectList const& mTotalAuraList = GetAuraEffectsByType(auratype);
5632 for (AuraEffectList::const_iterator i = mTotalAuraList.begin(); i != mTotalAuraList.end(); ++i)
5633 if (miscvalue == (*i)->GetMiscValue())
5634 return true;
5635 return false;
5636}

◆ HasAuraTypeWithTriggerSpell()

bool Unit::HasAuraTypeWithTriggerSpell ( AuraType  auratype,
uint32  triggerSpell 
) const
5657{
5658 for (AuraEffect const* aura : GetAuraEffectsByType(auratype))
5659 {
5660 if (aura->GetSpellInfo()->Effects[aura->GetEffIndex()].TriggerSpell == triggerSpell)
5661 {
5662 return true;
5663 }
5664 }
5665
5666 return false;
5667}

◆ HasAuraTypeWithValue()

bool Unit::HasAuraTypeWithValue ( AuraType  auratype,
int32  value 
) const
5648{
5649 AuraEffectList const& mTotalAuraList = GetAuraEffectsByType(auratype);
5650 for (AuraEffectList::const_iterator i = mTotalAuraList.begin(); i != mTotalAuraList.end(); ++i)
5651 if (value == (*i)->GetAmount())
5652 return true;
5653 return false;
5654}

◆ HasAuraWithMechanic()

bool Unit::HasAuraWithMechanic ( uint32  mechanicMask) const
5693{
5694 for (AuraApplicationMap::const_iterator iter = m_appliedAuras.begin(); iter != m_appliedAuras.end(); ++iter)
5695 {
5696 SpellInfo const* spellInfo = iter->second->GetBase()->GetSpellInfo();
5697 if (spellInfo->Mechanic && (mechanicMask & (1 << spellInfo->Mechanic)))
5698 return true;
5699
5700 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
5701 if (iter->second->HasEffect(i) && spellInfo->Effects[i].Effect && spellInfo->Effects[i].Mechanic)
5702 if (mechanicMask & (1 << spellInfo->Effects[i].Mechanic))
5703 return true;
5704 }
5705
5706 return false;
5707}
uint32 Mechanic
Definition: SpellInfo.h:321

◆ HasBreakableByDamageAuraType()

bool Unit::HasBreakableByDamageAuraType ( AuraType  type,
uint32  excludeAura = 0 
) const
782{
783 AuraEffectList const& auras = GetAuraEffectsByType(type);
784 for (AuraEffectList::const_iterator itr = auras.begin(); itr != auras.end(); ++itr)
785 if ((!excludeAura || excludeAura != (*itr)->GetSpellInfo()->Id) && //Avoid self interrupt of channeled Crowd Control spells like Seduction
786 ((*itr)->GetSpellInfo()->AuraInterruptFlags & AURA_INTERRUPT_FLAG_TAKE_DAMAGE))
787 return true;
788 return false;
789}

◆ HasBreakableByDamageCrowdControlAura()

bool Unit::HasBreakableByDamageCrowdControlAura ( Unit excludeCasterChannel = nullptr) const
792{
793 uint32 excludeAura = 0;
794 if (Spell* currentChanneledSpell = excludeCasterChannel ? excludeCasterChannel->GetCurrentSpell(CURRENT_CHANNELED_SPELL) : nullptr)
795 excludeAura = currentChanneledSpell->GetSpellInfo()->Id; //Avoid self interrupt of channeled Crowd Control spells like Seduction
796
802}
@ SPELL_AURA_MOD_FEAR
Definition: SpellAuraDefines.h:70
@ SPELL_AURA_MOD_ROOT
Definition: SpellAuraDefines.h:89
@ SPELL_AURA_MOD_CONFUSE
Definition: SpellAuraDefines.h:68
@ SPELL_AURA_MOD_STUN
Definition: SpellAuraDefines.h:75
bool HasBreakableByDamageAuraType(AuraType type, uint32 excludeAura=0) const
Definition: Unit.cpp:781
Spell * GetCurrentSpell(CurrentSpellTypes spellType) const
Definition: Unit.h:2058

◆ HasExtraUnitMovementFlag()

uint16 Unit::HasExtraUnitMovementFlag ( uint16  f) const
inline
2275{ return m_movementInfo.flags2 & f; }

◆ HasInvisibilityAura()

bool Unit::HasInvisibilityAura ( ) const
inline
@ SPELL_AURA_MOD_INVISIBILITY
Definition: SpellAuraDefines.h:81

◆ HasNegativeAuraWithAttribute()

bool Unit::HasNegativeAuraWithAttribute ( uint32  flag,
ObjectGuid  guid = ObjectGuid::Empty 
)
5682{
5683 for (AuraApplicationMap::const_iterator iter = m_appliedAuras.begin(); iter != m_appliedAuras.end(); ++iter)
5684 {
5685 Aura const* aura = iter->second->GetBase();
5686 if (!iter->second->IsPositive() && aura->GetSpellInfo()->Attributes & flag && (!guid || aura->GetCasterGUID() == guid))
5687 return true;
5688 }
5689 return false;
5690}
uint32 Attributes
Definition: SpellInfo.h:322

◆ HasNegativeAuraWithInterruptFlag()

bool Unit::HasNegativeAuraWithInterruptFlag ( uint32  flag,
ObjectGuid  guid = ObjectGuid::Empty 
)
5670{
5671 if (!(m_interruptMask & flag))
5672 return false;
5673 for (AuraApplicationList::iterator iter = m_interruptableAuras.begin(); iter != m_interruptableAuras.end(); ++iter)
5674 {
5675 if (!(*iter)->IsPositive() && (*iter)->GetBase()->GetSpellInfo()->AuraInterruptFlags & flag && (!guid || (*iter)->GetBase()->GetCasterGUID() == guid))
5676 return true;
5677 }
5678 return false;
5679}

◆ HasNpcFlag()

bool Unit::HasNpcFlag ( NPCFlags  flags) const
inline
1643{ return HasFlag(UNIT_NPC_FLAGS, flags) != 0; }

◆ HasSharedVision()

bool Unit::HasSharedVision ( ) const
inline
1889{ return !m_sharedVision.empty(); }

◆ HasSpell()

virtual bool Unit::HasSpell ( uint32  ) const
inlinevirtual

Reimplemented in Pet, Player, and Creature.

1699{ return false; }

◆ HasSpellCooldown()

virtual bool Unit::HasSpellCooldown ( uint32  ) const
inlinevirtual

Reimplemented in Creature, and Player.

2413{ return false; }

◆ HasSpellItemCooldown()

virtual bool Unit::HasSpellItemCooldown ( uint32  ,
uint32   
) const
inlinevirtual

Reimplemented in Player.

2414{ return false; }

◆ HasStealthAura()

bool Unit::HasStealthAura ( ) const
inline

◆ HasUnitFlag()

bool Unit::HasUnitFlag ( UnitFlags  flags) const
inline
1478{ return HasFlag(UNIT_FIELD_FLAGS, flags); }

◆ HasUnitFlag2()

bool Unit::HasUnitFlag2 ( UnitFlags2  flags) const
inline
1484{ return HasFlag(UNIT_FIELD_FLAGS_2, flags); }

◆ HasUnitMovementFlag()

bool Unit::HasUnitMovementFlag ( uint32  f) const
inline
2269{ return (m_movementInfo.flags & f) == f; }

◆ HasUnitState()

bool Unit::HasUnitState ( const uint32  f) const
inline
1398{ return (m_state & f); }

◆ HasUnitTypeMask()

uint32 Unit::HasUnitTypeMask ( uint32  mask) const
inline
1407{ return mask & m_unitTypeMask; }

◆ HasVisibleAuraType()

bool Unit::HasVisibleAuraType ( AuraType  auraType) const
5620{
5621 AuraEffectList const& mAuraList = GetAuraEffectsByType(auraType);
5622 for (AuraEffectList::const_iterator i = mAuraList.begin(); i != mAuraList.end(); ++i)
5623 if( (*i)->GetBase()->CanBeSentToClient() )
5624 return true;
5625
5626 return false;
5627}

◆ haveOffhandWeapon()

bool Unit::haveOffhandWeapon ( ) const
540{
541 if (Player const* player = ToPlayer())
542 return player->GetWeaponForAttack(OFF_ATTACK, true);
543
544 return CanDualWield();
545}
bool CanDualWield() const
Definition: Unit.h:1345

◆ HealBySpell()

int32 Unit::HealBySpell ( HealInfo healInfo,
bool  critical = false 
)
11191{
11192 uint32 heal = healInfo.GetHeal();
11193 sScriptMgr->ModifyHealReceived(this, healInfo.GetTarget(), heal, healInfo.GetSpellInfo());
11194 healInfo.SetHeal(heal);
11195
11196 // calculate heal absorb and reduce healing
11197 CalcHealAbsorb(healInfo);
11198
11199 int32 gain = Unit::DealHeal(healInfo.GetHealer(), healInfo.GetTarget(), healInfo.GetHeal());
11200 SendHealSpellLog(healInfo.GetTarget(), healInfo.GetSpellInfo()->Id, healInfo.GetHeal(), uint32(healInfo.GetHeal() - gain), healInfo.GetAbsorb(), critical);
11201 return gain;
11202}
Unit * GetHealer() const
Definition: Unit.h:830
uint32 GetAbsorb() const
Definition: Unit.h:833
void SetHeal(uint32 amount)
Definition: Unit.h:825
static void CalcHealAbsorb(HealInfo &healInfo)
Definition: Unit.cpp:2452
static int32 DealHeal(Unit *healer, Unit *victim, uint32 addhealth)
Definition: Unit.cpp:10899
void SendHealSpellLog(Unit *victim, uint32 SpellID, uint32 Damage, uint32 OverHeal, uint32 Absorb, bool critical=false)
Definition: Unit.cpp:11175

◆ HealthAbovePct()

bool Unit::HealthAbovePct ( int32  pct) const
inline
1444{ return GetHealth() > CountPctFromMaxHealth(pct); }

◆ HealthAbovePctHealed()

bool Unit::HealthAbovePctHealed ( int32  pct,
uint32  heal 
) const
inline
1445{ return uint64(GetHealth()) + uint64(heal) > CountPctFromMaxHealth(pct); }

◆ HealthBelowPct()

bool Unit::HealthBelowPct ( int32  pct) const
inline
1442{ return GetHealth() < CountPctFromMaxHealth(pct); }

◆ HealthBelowPctDamaged()

bool Unit::HealthBelowPctDamaged ( int32  pct,
uint32  damage 
) const
inline
1443{ return int64(GetHealth()) - int64(damage) < int64(CountPctFromMaxHealth(pct)); }
std::int64_t int64
Definition: Define.h:103

◆ IncrDiminishing()

void Unit::IncrDiminishing ( DiminishingGroup  group)
14891{
14892 // Checking for existing in the table
14893 for (Diminishing::iterator i = m_Diminishing.begin(); i != m_Diminishing.end(); ++i)
14894 {
14895 if (i->DRGroup != group)
14896 continue;
14897 if (int32(i->hitCount) < GetDiminishingReturnsMaxLevel(group))
14898 i->hitCount += 1;
14899 return;
14900 }
14902}
DiminishingLevels GetDiminishingReturnsMaxLevel(DiminishingGroup group)
Definition: SpellMgr.cpp:265
Definition: Unit.h:703

◆ InitCharmInfo()

CharmInfo * Unit::InitCharmInfo ( )
15650{
15651 if (!m_charmInfo)
15652 m_charmInfo = new CharmInfo(this);
15653
15654 return m_charmInfo;
15655}
Definition: Unit.h:1094

◆ InitStatBuffMods()

void Unit::InitStatBuffMods ( )
inline
2027 {
2028 for (uint8 i = STAT_STRENGTH; i < MAX_STATS; ++i) SetFloatValue(static_cast<uint16>(UNIT_FIELD_POSSTAT0) + i, 0);
2029 for (uint8 i = STAT_STRENGTH; i < MAX_STATS; ++i) SetFloatValue(static_cast<uint16>(UNIT_FIELD_NEGSTAT0) + i, 0);
2030 }

◆ InitTamedPet()

bool Unit::InitTamedPet ( Pet pet,
uint8  level,
uint32  spell_id 
)
17446{
17447 Player* player = ToPlayer();
17448 PetStable& petStable = player->GetOrInitPetStable();
17449 if (petStable.CurrentPet || petStable.GetUnslottedHunterPet())
17450 return false;
17451
17452 pet->SetCreatorGUID(GetGUID());
17453 pet->SetFaction(GetFaction());
17454 pet->SetUInt32Value(UNIT_CREATED_BY_SPELL, spell_id);
17455
17456 if (GetTypeId() == TYPEID_PLAYER)
17458
17459 if (!pet->InitStatsForLevel(level))
17460 {
17461 LOG_ERROR("entities.unit", "Pet::InitStatsForLevel() failed for creature (Entry: {})!", pet->GetEntry());
17462 return false;
17463 }
17464
17465 pet->GetCharmInfo()->SetPetNumber(sObjectMgr->GeneratePetNumber(), true);
17466 // this enables pet details window (Shift+P)
17467 pet->InitPetCreateSpells();
17468 pet->SetFullHealth();
17469 pet->FillPetInfo(&petStable.CurrentPet.emplace());
17470 return true;
17471}
@ UNIT_CREATED_BY_SPELL
Definition: UpdateFields.h:138
bool InitStatsForLevel(uint8 level)
Definition: Pet.cpp:1009
void FillPetInfo(PetStable::PetInfo *petInfo) const
Definition: Pet.cpp:2419
void InitPetCreateSpells()
Definition: Pet.cpp:2013
Definition: PetDefines.h:197
PetInfo const * GetUnslottedHunterPet() const
Definition: PetDefines.h:225
Optional< PetInfo > CurrentPet
Definition: PetDefines.h:220
PetStable & GetOrInitPetStable()
Definition: Player.cpp:15272
void SetFullHealth()
Definition: Unit.h:1453
void SetFaction(uint32 faction)
Definition: Unit.cpp:10017
void ReplaceAllUnitFlags(UnitFlags flags)
Definition: Unit.h:1481
CharmInfo * GetCharmInfo()
Definition: Unit.h:1880
void SetCreatorGUID(ObjectGuid creator)
Definition: Unit.h:1814
void SetPetNumber(uint32 petnumber, bool statwindow)
Definition: Unit.cpp:15864

◆ InterruptNonMeleeSpells()

void Unit::InterruptNonMeleeSpells ( bool  withDelayed,
uint32  spellid = 0,
bool  withInstant = true,
bool  bySelf = false 
)
4058{
4059 // generic spells are interrupted if they are not finished or delayed
4060 if (m_currentSpells[CURRENT_GENERIC_SPELL] && (!spell_id || m_currentSpells[CURRENT_GENERIC_SPELL]->m_spellInfo->Id == spell_id))
4061 InterruptSpell(CURRENT_GENERIC_SPELL, withDelayed, withInstant, bySelf);
4062
4063 // autorepeat spells are interrupted if they are not finished or delayed
4064 if (m_currentSpells[CURRENT_AUTOREPEAT_SPELL] && (!spell_id || m_currentSpells[CURRENT_AUTOREPEAT_SPELL]->m_spellInfo->Id == spell_id))
4065 InterruptSpell(CURRENT_AUTOREPEAT_SPELL, withDelayed, withInstant, bySelf);
4066
4067 // channeled spells are interrupted if they are not finished, even if they are delayed
4068 if (m_currentSpells[CURRENT_CHANNELED_SPELL] && (!spell_id || m_currentSpells[CURRENT_CHANNELED_SPELL]->m_spellInfo->Id == spell_id))
4069 InterruptSpell(CURRENT_CHANNELED_SPELL, true, true, bySelf);
4070}

◆ InterruptSpell()

void Unit::InterruptSpell ( CurrentSpellTypes  spellType,
bool  withDelayed = true,
bool  withInstant = true,
bool  bySelf = false 
)
3991{
3992 //LOG_DEBUG("entities.unit", "Interrupt spell for unit {}.", GetEntry());
3993 Spell* spell = m_currentSpells[spellType];
3994 if (spell
3995 && (withDelayed || spell->getState() != SPELL_STATE_DELAYED)
3996 && (withInstant || spell->GetCastTime() > 0 || spell->getState() == SPELL_STATE_CASTING)) // xinef: or spell is in casting state (channeled spells only)
3997 {
3998 // for example, do not let self-stun aura interrupt itself
3999 if (!spell->IsInterruptable())
4000 return;
4001
4002 // send autorepeat cancel message for autorepeat spells
4003 if (spellType == CURRENT_AUTOREPEAT_SPELL)
4004 if (GetTypeId() == TYPEID_PLAYER)
4006
4007 if (spell->getState() != SPELL_STATE_FINISHED)
4008 spell->cancel(bySelf);
4009
4010 m_currentSpells[spellType] = nullptr;
4011 spell->SetReferencedFromCurrent(false);
4012 }
4013}
@ SPELL_STATE_DELAYED
Definition: Spell.h:228
void SendAutoRepeatCancel(Unit *target)
Definition: PlayerMisc.cpp:152
bool IsInterruptable() const
Definition: Spell.h:559
int32 GetCastTime() const
Definition: Spell.h:547
uint32 getState() const
Definition: Spell.h:482
void cancel(bool bySelf=false)
Definition: Spell.cpp:3681

◆ IsAlive()

bool Unit::IsAlive ( ) const
inline
1805{ return (m_deathState == ALIVE); };

◆ IsAlwaysDetectableFor()

bool Unit::IsAlwaysDetectableFor ( WorldObject const *  seer) const
overrideprotectedvirtual

Reimplemented from WorldObject.

14100{
14102 return true;
14103
14104 if (HasAuraTypeWithCaster(SPELL_AURA_MOD_STALKED, seer->GetGUID()))
14105 return true;
14106
14107 if (Player* ownerPlayer = GetSpellModOwner())
14108 if (Player const* seerPlayer = seer->ToPlayer())
14109 {
14110 if (ownerPlayer->IsGroupVisibleFor(seerPlayer))
14111 return true;
14112 }
14113
14114 return false;
14115}
virtual bool IsAlwaysDetectableFor(WorldObject const *) const
Definition: Object.h:651

◆ IsAlwaysVisibleFor()

bool Unit::IsAlwaysVisibleFor ( WorldObject const *  seer) const
overrideprotectedvirtual

Reimplemented from WorldObject.

14081{
14083 return true;
14084
14085 // Always seen by owner
14086 if (ObjectGuid guid = GetCharmerOrOwnerGUID())
14087 if (seer->GetGUID() == guid)
14088 return true;
14089
14090 if (Player const* seerPlayer = seer->ToPlayer())
14091 if (Unit* owner = GetOwner())
14092 if (Player* ownerPlayer = owner->ToPlayer())
14093 if (ownerPlayer->IsGroupVisibleFor(seerPlayer))
14094 return true;
14095
14096 return false;
14097}
virtual bool IsAlwaysVisibleFor(WorldObject const *) const
Definition: Object.h:648

◆ IsArmorer()

bool Unit::IsArmorer ( ) const
inline
@ UNIT_NPC_FLAG_REPAIR
Definition: Unit.h:528
bool HasNpcFlag(NPCFlags flags) const
Definition: Unit.h:1643

◆ isAttackingPlayer()

bool Unit::isAttackingPlayer ( ) const
10414{
10416 return true;
10417
10418 if (!m_Controlled.empty())
10419 for (ControlSet::const_iterator itr = m_Controlled.begin(); itr != m_Controlled.end(); ++itr)
10420 if ((*itr)->isAttackingPlayer())
10421 return true;
10422
10423 for (uint8 i = 0; i < MAX_SUMMON_SLOT; ++i)
10424 if (m_SummonSlot[i])
10425 if (Creature* summon = GetMap()->GetCreature(m_SummonSlot[i]))
10426 if (summon->isAttackingPlayer())
10427 return true;
10428
10429 return false;
10430}

◆ isAttackReady()

bool Unit::isAttackReady ( WeaponAttackType  type = BASE_ATTACK) const
inline
1343{ return m_attackTimer[type] <= 0; }

◆ IsAuctioner()

bool Unit::IsAuctioner ( ) const
inline
@ UNIT_NPC_FLAG_AUCTIONEER
Definition: Unit.h:537

◆ IsBanker()

bool Unit::IsBanker ( ) const
inline
@ UNIT_NPC_FLAG_BANKER
Definition: Unit.h:533

◆ IsBattleMaster()

bool Unit::IsBattleMaster ( ) const
inline
@ UNIT_NPC_FLAG_BATTLEMASTER
Definition: Unit.h:536

◆ isBeingLoaded()

virtual bool Unit::isBeingLoaded ( ) const
inlinevirtual

Reimplemented in Pet, and Player.

2390{ return false;}

◆ isBlockCritical()

bool Unit::isBlockCritical ( )
3069{
3071 return true;
3072 return false;
3073}
@ SPELL_AURA_MOD_BLOCK_CRIT_CHANCE
Definition: SpellAuraDefines.h:316

◆ IsCharmed()

bool Unit::IsCharmed ( ) const
inline
1868{ return GetCharmerGUID(); }

◆ IsCharmedOwnedByPlayerOrPlayer()

bool Unit::IsCharmedOwnedByPlayerOrPlayer ( ) const
inline
ObjectGuid GetCharmerOrOwnerOrOwnGUID() const
Definition: Unit.h:1828

◆ IsContestedGuard()

bool Unit::IsContestedGuard ( ) const
inline
1508 {
1509 if (FactionTemplateEntry const* entry = GetFactionTemplateEntry())
1510 return entry->IsContestedGuardFaction();
1511
1512 return false;
1513 }

◆ IsControllableGuardian()

bool Unit::IsControllableGuardian ( ) const
inline

◆ IsControlledByPlayer()

bool Unit::IsControlledByPlayer ( ) const
inline
1825{ return m_ControlledByPlayer; }

◆ IsCreatedByPlayer()

bool Unit::IsCreatedByPlayer ( ) const
inline
1826{ return m_CreatedByPlayer; }

◆ IsCritter()

bool Unit::IsCritter ( ) const
inline
@ CREATURE_TYPE_CRITTER
Definition: SharedDefines.h:2607

◆ IsDamageReducedByArmor()

bool Unit::IsDamageReducedByArmor ( SpellSchoolMask  damageSchoolMask,
SpellInfo const *  spellInfo = nullptr,
uint8  effIndex = MAX_SPELL_EFFECTS 
)
static
1967{
1968 // only physical spells damage gets reduced by armor
1969 if ((schoolMask & SPELL_SCHOOL_MASK_NORMAL) == 0)
1970 return false;
1971 if (spellInfo)
1972 {
1973 // there are spells with no specific attribute but they have "ignores armor" in tooltip
1974 if (spellInfo->HasAttribute(SPELL_ATTR0_CU_IGNORE_ARMOR))
1975 return false;
1976
1977 // bleeding effects are not reduced by armor
1978 if (effIndex != MAX_SPELL_EFFECTS)
1979 {
1980 if (spellInfo->Effects[effIndex].ApplyAuraName == SPELL_AURA_PERIODIC_DAMAGE ||
1981 spellInfo->Effects[effIndex].Effect == SPELL_EFFECT_SCHOOL_DAMAGE)
1982 if (spellInfo->GetEffectMechanicMask(effIndex) & (1 << MECHANIC_BLEED))
1983 return false;
1984 }
1985 }
1986 return true;
1987}
@ MECHANIC_BLEED
Definition: SharedDefines.h:1312
@ SPELL_ATTR0_CU_IGNORE_ARMOR
Definition: SpellInfo.h:191

◆ isDead()

bool Unit::isDead ( ) const
inline
1807{ return (m_deathState == DEAD || m_deathState == CORPSE); };
@ CORPSE
Definition: Unit.h:318
@ DEAD
Definition: Unit.h:319

◆ IsDuringRemoveFromWorld()

bool Unit::IsDuringRemoveFromWorld ( ) const
inline

◆ isDying()

bool Unit::isDying ( ) const
inline
1806{ return (m_deathState == JUST_DIED); };

◆ IsEngaged()

bool Unit::IsEngaged ( ) const
inline
1682{ return IsInCombat(); }
bool IsInCombat() const
Definition: Unit.h:1685

◆ IsEngagedBy()

bool Unit::IsEngagedBy ( Unit const *  who) const
inline
1683{ return IsInCombatWith(who); }

◆ IsFalling()

bool Unit::IsFalling ( ) const
19963{
19965}
@ MOVEMENTFLAG_FALLING_FAR
Definition: Unit.h:565
bool isFalling() const
Definition: MoveSpline.h:118
bool HasMovementFlag(uint32 flag) const
Definition: Object.h:322

◆ isFeared()

bool Unit::isFeared ( ) const
inline

◆ IsFFAPvP()

bool Unit::IsFFAPvP ( ) const
inline
@ UNIT_BYTE2_FLAG_FFA_PVP
Definition: Unit.h:138

◆ IsFlying()

bool Unit::IsFlying ( ) const
inline
@ MOVEMENTFLAG_DISABLE_GRAVITY
Definition: Unit.h:562

◆ IsFriendlyTo()

bool Unit::IsFriendlyTo ( Unit const *  unit) const
10203{
10204 return GetReactionTo(unit) >= REP_FRIENDLY;
10205}

◆ isFrozen()

bool Unit::isFrozen ( ) const
15928{
15930}
@ AURA_STATE_FROZEN
Definition: SharedDefines.h:1267

◆ IsFullHealth()

bool Unit::IsFullHealth ( ) const
inline
1441{ return GetHealth() == GetMaxHealth(); }

◆ IsGossip()

bool Unit::IsGossip ( ) const
inline

◆ IsGuardian()

bool Unit::IsGuardian ( ) const
inline

◆ IsGuildMaster()

bool Unit::IsGuildMaster ( ) const
inline
@ UNIT_NPC_FLAG_PETITIONER
Definition: Unit.h:534

◆ IsHostileTo()

bool Unit::IsHostileTo ( Unit const *  unit) const
10198{
10199 return GetReactionTo(unit) <= REP_HOSTILE;
10200}

◆ IsHostileToPlayers()

bool Unit::IsHostileToPlayers ( ) const
10208{
10209 FactionTemplateEntry const* my_faction = GetFactionTemplateEntry();
10210 if (!my_faction || !my_faction->faction)
10211 return false;
10212
10213 FactionEntry const* raw_faction = sFactionStore.LookupEntry(my_faction->faction);
10214 if (raw_faction && raw_faction->reputationListID >= 0)
10215 return false;
10216
10217 return my_faction->IsHostileToPlayers();
10218}
int32 reputationListID
Definition: DBCStructure.h:900
uint32 faction
Definition: DBCStructure.h:932
bool IsHostileToPlayers() const
Definition: DBCStructure.h:972

◆ IsHovering()

bool Unit::IsHovering ( ) const
inline
@ MOVEMENTFLAG_HOVER
Definition: Unit.h:582

◆ IsHunterPet()

bool Unit::IsHunterPet ( ) const
inline
@ UNIT_MASK_HUNTER_PET
Definition: Unit.h:682

◆ IsImmunedToDamage() [1/3]

bool Unit::IsImmunedToDamage ( Spell const *  spell) const
12700{
12701 SpellInfo const* spellInfo = spell->GetSpellInfo();
12702 if (!spellInfo)
12703 {
12704 return false;
12705 }
12706
12708 {
12709 return false;
12710 }
12711
12713 {
12714 return false;
12715 }
12716
12717 uint32 schoolMask = spell->GetSpellSchoolMask();
12718 if (schoolMask == SPELL_SCHOOL_MASK_NONE)
12719 {
12720 return false;
12721 }
12722
12723 // If m_immuneToDamage type contain magic, IMMUNE damage.
12724 SpellImmuneList const& damageList = m_spellImmune[IMMUNITY_DAMAGE];
12725 for (SpellImmuneList::const_iterator itr = damageList.begin(); itr != damageList.end(); ++itr)
12726 {
12727 if ((itr->type & schoolMask) == schoolMask)
12728 {
12729 return true;
12730 }
12731 }
12732
12733 return false;
12734}
@ SPELL_ATTR2_NO_SCHOOL_IMMUNITIES
Definition: SharedDefines.h:454
@ SPELL_ATTR1_IMMUNITY_TO_HOSTILE_AND_FRIENDLY_EFFECTS
Definition: SharedDefines.h:407
@ IMMUNITY_DAMAGE
Definition: SharedDefines.h:1369
@ SPELL_SCHOOL_MASK_NONE
Definition: SharedDefines.h:268
std::vector< SpellImmune > SpellImmuneList
Definition: SpellDefines.h:179

◆ IsImmunedToDamage() [2/3]

bool Unit::IsImmunedToDamage ( SpellInfo const *  spellInfo) const
12668{
12669 if (!spellInfo)
12670 {
12671 return false;
12672 }
12673
12675 {
12676 return false;
12677 }
12678
12679 if (spellInfo->HasAttribute(SPELL_ATTR1_IMMUNITY_TO_HOSTILE_AND_FRIENDLY_EFFECTS) || spellInfo->HasAttribute(SPELL_ATTR2_NO_SCHOOL_IMMUNITIES))
12680 {
12681 return false;
12682 }
12683
12684 uint32 schoolMask = spellInfo->GetSchoolMask();
12685 if (schoolMask == SPELL_SCHOOL_MASK_NONE)
12686 {
12687 return false;
12688 }
12689
12690 // If m_immuneToDamage type contain magic, IMMUNE damage.
12691 SpellImmuneList const& damageList = m_spellImmune[IMMUNITY_DAMAGE];
12692 for (SpellImmuneList::const_iterator itr = damageList.begin(); itr != damageList.end(); ++itr)
12693 if((itr->type & schoolMask) == schoolMask)
12694 return true;
12695
12696 return false;
12697}

◆ IsImmunedToDamage() [3/3]

bool Unit::IsImmunedToDamage ( SpellSchoolMask  meleeSchoolMask) const
12652{
12653 if (meleeSchoolMask == SPELL_SCHOOL_MASK_NONE)
12654 {
12655 return false;
12656 }
12657
12658 // If m_immuneToDamage type contain magic, IMMUNE damage.
12659 SpellImmuneList const& damageList = m_spellImmune[IMMUNITY_DAMAGE];
12660 for (SpellImmuneList::const_iterator itr = damageList.begin(); itr != damageList.end(); ++itr)
12661 if((itr->type & meleeSchoolMask) == meleeSchoolMask)
12662 return true;
12663
12664 return false;
12665}

◆ IsImmunedToDamageOrSchool() [1/2]

bool Unit::IsImmunedToDamageOrSchool ( SpellInfo const *  spellInfo) const
12816{
12817 return IsImmunedToDamage(spellInfo) || IsImmunedToSchool(spellInfo);
12818}
bool IsImmunedToSchool(SpellSchoolMask meleeSchoolMask) const
Definition: Unit.cpp:12736
bool IsImmunedToDamage(SpellSchoolMask meleeSchoolMask) const
Definition: Unit.cpp:12651

◆ IsImmunedToDamageOrSchool() [2/2]

bool Unit::IsImmunedToDamageOrSchool ( SpellSchoolMask  meleeSchoolMask) const
12806{
12807 if (meleeSchoolMask == SPELL_SCHOOL_MASK_NONE)
12808 {
12809 return false;
12810 }
12811
12812 return IsImmunedToDamage(meleeSchoolMask) || IsImmunedToSchool(meleeSchoolMask);
12813}

◆ IsImmunedToSchool() [1/3]

bool Unit::IsImmunedToSchool ( Spell const *  spell) const
12776{
12777 SpellInfo const* spellInfo = spell->GetSpellInfo();
12779 {
12780 return false;
12781 }
12782
12783 uint32 schoolMask = spell->GetSpellSchoolMask();
12784 if (schoolMask == SPELL_SCHOOL_MASK_NONE)
12785 {
12786 return false;
12787 }
12788
12789 if (spellInfo->Id != 42292 && spellInfo->Id != 59752 && spellInfo->Id != 19574 && spellInfo->Id != 34471)
12790 {
12791 // If m_immuneToSchool type contain this school type, IMMUNE damage.
12792 SpellImmuneList const& schoolList = m_spellImmune[IMMUNITY_SCHOOL];
12793 for (SpellImmuneList::const_iterator itr = schoolList.begin(); itr != schoolList.end(); ++itr)
12794 {
12795 if ((itr->type & schoolMask) == schoolMask && !spellInfo->CanPierceImmuneAura(sSpellMgr->GetSpellInfo(itr->spellId)))
12796 {
12797 return true;
12798 }
12799 }
12800 }
12801
12802 return false;
12803}
@ IMMUNITY_SCHOOL
Definition: SharedDefines.h:1368
bool CanPierceImmuneAura(SpellInfo const *aura) const
Definition: SpellInfo.cpp:1306

◆ IsImmunedToSchool() [2/3]

bool Unit::IsImmunedToSchool ( SpellInfo const *  spellInfo) const
12753{
12755 return false;
12756
12757 uint32 schoolMask = spellInfo->GetSchoolMask();
12758 if (schoolMask == SPELL_SCHOOL_MASK_NONE)
12759 {
12760 return false;
12761 }
12762
12763 if (spellInfo->Id != 42292 && spellInfo->Id != 59752 && spellInfo->Id != 19574 && spellInfo->Id != 34471)
12764 {
12765 // If m_immuneToSchool type contain this school type, IMMUNE damage.
12766 SpellImmuneList const& schoolList = m_spellImmune[IMMUNITY_SCHOOL];
12767 for (SpellImmuneList::const_iterator itr = schoolList.begin(); itr != schoolList.end(); ++itr)
12768 if((itr->type & schoolMask) == schoolMask && !spellInfo->CanPierceImmuneAura(sSpellMgr->GetSpellInfo(itr->spellId)))
12769 return true;
12770 }
12771
12772 return false;
12773}

◆ IsImmunedToSchool() [3/3]

bool Unit::IsImmunedToSchool ( SpellSchoolMask  meleeSchoolMask) const
12737{
12738 if (meleeSchoolMask == SPELL_SCHOOL_MASK_NONE)
12739 {
12740 return false;
12741 }
12742
12743 // If m_immuneToSchool type contain this school type, IMMUNE damage.
12744 SpellImmuneList const& schoolList = m_spellImmune[IMMUNITY_SCHOOL];
12745 for (SpellImmuneList::const_iterator itr = schoolList.begin(); itr != schoolList.end(); ++itr)
12746 if((itr->type & meleeSchoolMask) == meleeSchoolMask)
12747 return true;
12748
12749 return false;
12750}

◆ IsImmunedToSpell()

bool Unit::IsImmunedToSpell ( SpellInfo const *  spellInfo,
Spell const *  spell = nullptr 
)
virtual

Reimplemented in Creature.

12821{
12822 if (!spellInfo)
12823 return false;
12824
12825 // Single spell immunity.
12826 SpellImmuneList const& idList = m_spellImmune[IMMUNITY_ID];
12827 for (SpellImmuneList::const_iterator itr = idList.begin(); itr != idList.end(); ++itr)
12828 if (itr->type == spellInfo->Id)
12829 return true;
12830
12831 // xinef: my special immunity, if spellid is not on this list it means npc is immune
12832 SpellImmuneList const& allowIdList = m_spellImmune[IMMUNITY_ALLOW_ID];
12833 if (!allowIdList.empty())
12834 {
12835 for (SpellImmuneList::const_iterator itr = allowIdList.begin(); itr != allowIdList.end(); ++itr)
12836 if (itr->type == spellInfo->Id)
12837 return false;
12838 return true;
12839 }
12840
12842 return false;
12843
12844 if (spellInfo->Dispel)
12845 {
12846 SpellImmuneList const& dispelList = m_spellImmune[IMMUNITY_DISPEL];
12847 for (SpellImmuneList::const_iterator itr = dispelList.begin(); itr != dispelList.end(); ++itr)
12848 if (itr->type == spellInfo->Dispel)
12849 return true;
12850 }
12851
12852 // Spells that don't have effectMechanics.
12853 if (spellInfo->Mechanic)
12854 {
12855 SpellImmuneList const& mechanicList = m_spellImmune[IMMUNITY_MECHANIC];
12856 for (SpellImmuneList::const_iterator itr = mechanicList.begin(); itr != mechanicList.end(); ++itr)
12857 if (itr->type == spellInfo->Mechanic)
12858 return true;
12859 }
12860
12861 bool immuneToAllEffects = true;
12862 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
12863 {
12864 // State/effect immunities applied by aura expect full spell immunity
12865 // Ignore effects with mechanic, they are supposed to be checked separately
12866 if (!spellInfo->Effects[i].IsEffect())
12867 continue;
12868
12869 // Xinef: if target is immune to one effect, and the spell has transform aura - it is immune to whole spell
12870 if (IsImmunedToSpellEffect(spellInfo, i))
12871 {
12872 if (spellInfo->HasAura(SPELL_AURA_TRANSFORM))
12873 return true;
12874 continue;
12875 }
12876
12877 immuneToAllEffects = false;
12878 break;
12879 }
12880 if (immuneToAllEffects) //Return immune only if the target is immune to all spell effects.
12881 return true;
12882
12883 if (spellInfo->Id != 42292 && spellInfo->Id != 59752 && spellInfo->Id != 19574 && spellInfo->Id != 34471)
12884 {
12885 SpellSchoolMask spellSchoolMask = spellInfo->GetSchoolMask();
12886 if (spell)
12887 {
12888 spellSchoolMask = spell->GetSpellSchoolMask();
12889 }
12890
12891 if (spellSchoolMask != SPELL_SCHOOL_MASK_NONE)
12892 {
12893 SpellImmuneList const& schoolList = m_spellImmune[IMMUNITY_SCHOOL];
12894 for (SpellImmuneList::const_iterator itr = schoolList.begin(); itr != schoolList.end(); ++itr)
12895 {
12896 SpellInfo const* immuneSpellInfo = sSpellMgr->GetSpellInfo(itr->spellId);
12897 if (((itr->type & spellSchoolMask) == spellSchoolMask)
12898 && (!immuneSpellInfo || immuneSpellInfo->IsPositive()) && !spellInfo->IsPositive()
12899 && !spellInfo->CanPierceImmuneAura(immuneSpellInfo))
12900 {
12901 return true;
12902 }
12903 }
12904 }
12905 }
12906
12907 return false;
12908}
@ IMMUNITY_ALLOW_ID
Definition: SharedDefines.h:1373
@ IMMUNITY_ID
Definition: SharedDefines.h:1372
@ IMMUNITY_MECHANIC
Definition: SharedDefines.h:1371

◆ IsImmunedToSpellEffect()

bool Unit::IsImmunedToSpellEffect ( SpellInfo const *  spellInfo,
uint32  index 
) const
virtual

Reimplemented in Creature, and Totem.

12911{
12912 if (!spellInfo || !spellInfo->Effects[index].IsEffect())
12913 return false;
12914
12915 // xinef: pet scaling auras
12916 if (spellInfo->HasAttribute(SPELL_ATTR4_OWNER_POWER_SCALING))
12917 return false;
12918
12920 return false;
12921
12922 //If m_immuneToEffect type contain this effect type, IMMUNE effect.
12923 uint32 effect = spellInfo->Effects[index].Effect;
12924 SpellImmuneList const& effectList = m_spellImmune[IMMUNITY_EFFECT];
12925 for (SpellImmuneList::const_iterator itr = effectList.begin(); itr != effectList.end(); ++itr)
12926 {
12927 if (itr->type == effect && (itr->spellId != 62692 || (spellInfo->Effects[index].MiscValue == POWER_MANA && !CanRestoreMana(spellInfo))))
12928 {
12929 return true;
12930 }
12931 }
12932
12933 if (uint32 mechanic = spellInfo->Effects[index].Mechanic)
12934 {
12935 SpellImmuneList const& mechanicList = m_spellImmune[IMMUNITY_MECHANIC];
12936 for (SpellImmuneList::const_iterator itr = mechanicList.begin(); itr != mechanicList.end(); ++itr)
12937 if (itr->type == mechanic)
12938 return true;
12939 }
12940
12941 if (uint32 aura = spellInfo->Effects[index].ApplyAuraName)
12942 {
12944 for (SpellImmuneList::const_iterator itr = list.begin(); itr != list.end(); ++itr)
12945 {
12946 if (itr->type == aura && (itr->spellId != 64848 || (spellInfo->Effects[index].MiscValue == POWER_MANA && !CanRestoreMana(spellInfo))))
12947 {
12948 if (!spellInfo->HasAttribute(SPELL_ATTR3_ALWAYS_HIT))
12949 {
12950 if (itr->blockType == SPELL_BLOCK_TYPE_ALL || spellInfo->IsPositive()) // xinef: added for pet scaling
12951 {
12952 return true;
12953 }
12954 }
12955 }
12956 }
12957
12958 if (!spellInfo->HasAttribute(SPELL_ATTR2_NO_SCHOOL_IMMUNITIES))
12959 {
12960 // Check for immune to application of harmful magical effects
12962 for (AuraEffectList::const_iterator iter = immuneAuraApply.begin(); iter != immuneAuraApply.end(); ++iter)
12963 {
12964 if (/*(spellInfo->Dispel == DISPEL_MAGIC || spellInfo->Dispel == DISPEL_CURSE || spellInfo->Dispel == DISPEL_DISEASE) &&*/ // Magic debuff, xinef: all kinds?
12965 ((*iter)->GetMiscValue() & spellInfo->GetSchoolMask()) && // Check school
12966 !spellInfo->IsPositiveEffect(index) && // Harmful
12967 spellInfo->Effects[index].Effect != SPELL_EFFECT_PERSISTENT_AREA_AURA) // Not Persistent area auras
12968 {
12969 return true;
12970 }
12971 }
12972 }
12973 }
12974
12975 return false;
12976}
@ SPELL_EFFECT_PERSISTENT_AREA_AURA
Definition: SharedDefines.h:777
@ SPELL_ATTR3_ALWAYS_HIT
Definition: SharedDefines.h:483
@ IMMUNITY_STATE
Definition: SharedDefines.h:1367
@ IMMUNITY_EFFECT
Definition: SharedDefines.h:1366
@ SPELL_ATTR4_OWNER_POWER_SCALING
Definition: SharedDefines.h:527
@ SPELL_AURA_MOD_IMMUNE_AURA_APPLY_SCHOOL
Definition: SpellAuraDefines.h:330
@ SPELL_BLOCK_TYPE_ALL
Definition: SpellDefines.h:156
bool CanRestoreMana(SpellInfo const *spellInfo) const
Definition: Unit.cpp:21220

◆ IsImmuneToAll()

bool Unit::IsImmuneToAll ( ) const
inline
1676{ return IsImmuneToPC() && IsImmuneToNPC(); }

◆ IsImmuneToNPC()

bool Unit::IsImmuneToNPC ( ) const
inline
@ UNIT_FLAG_IMMUNE_TO_NPC
Definition: Unit.h:457

◆ IsImmuneToPC()

bool Unit::IsImmuneToPC ( ) const
inline

◆ isInAccessiblePlaceFor()

bool Unit::isInAccessiblePlaceFor ( Creature const *  c) const
4122{
4123 if (c->GetMapId() == 618) // Ring of Valor
4124 {
4125 // skip transport check, check for being below floor level
4126 if (this->GetPositionZ() < 28.0f)
4127 return false;
4128 if (BattlegroundMap* bgMap = c->GetMap()->ToBattlegroundMap())
4129 if (Battleground* bg = bgMap->GetBG())
4130 if (bg->GetStartTime() < 80133) // 60000ms preparation time + 20133ms elevator rise time
4131 return false;
4132 }
4133 else if (c->GetMapId() == 631) // Icecrown Citadel
4134 {
4135 // if static transport doesn't match - return false
4136 if (c->GetTransport() != this->GetTransport() && ((c->GetTransport() && c->GetTransport()->IsStaticTransport()) || (this->GetTransport() && this->GetTransport()->IsStaticTransport())))
4137 return false;
4138
4139 // special handling for ICC (map 631), for non-flying pets in Gunship Battle, for trash npcs this is done via CanAIAttack
4140 if (c->GetOwnerGUID().IsPlayer() && !c->CanFly())
4141 {
4142 if (c->GetTransport() != this->GetTransport())
4143 return false;
4144 if (this->GetTransport())
4145 {
4146 if (c->GetPositionY() < 2033.0f)
4147 {
4148 if (this->GetPositionY() > 2033.0f)
4149 return false;
4150 }
4151 else if (c->GetPositionY() < 2438.0f)
4152 {
4153 if (this->GetPositionY() < 2033.0f || this->GetPositionY() > 2438.0f)
4154 return false;
4155 }
4156 else if (this->GetPositionY() < 2438.0f)
4157 return false;
4158 }
4159 }
4160 }
4161 else
4162 {
4163 // pussywizard: prevent any bugs by passengers exiting transports or normal creatures flying away
4164 if (c->GetTransport() != this->GetTransport())
4165 return false;
4166 }
4167
4168 LiquidStatus liquidStatus = GetLiquidData().Status;
4169 bool isInWater = (liquidStatus & MAP_LIQUID_STATUS_SWIMMING) != 0;
4170
4171 // In water or jumping in water
4172 if (isInWater || (liquidStatus == LIQUID_MAP_ABOVE_WATER && (IsFalling() || (ToPlayer() && ToPlayer()->IsFalling()))))
4173 {
4174 return c->CanEnterWater();
4175 }
4176 else
4177 {
4178 return c->CanWalk() || c->CanFly();
4179 }
4180}
LiquidStatus
Definition: Map.h:142
@ LIQUID_MAP_ABOVE_WATER
Definition: Map.h:144
#define MAP_LIQUID_STATUS_SWIMMING
Definition: Map.h:150
Definition: Map.h:847
BattlegroundMap * ToBattlegroundMap()
Definition: Map.h:547
bool IsFalling() const
Definition: Unit.cpp:19962
LiquidData const & GetLiquidData() const
Definition: Object.cpp:3091
LiquidStatus Status
Definition: Map.h:177

◆ isInBackInMap()

bool Unit::isInBackInMap ( Unit const *  target,
float  distance,
float  arc = M_PI 
) const
4117{
4118 return IsWithinDistInMap(target, distance) && !HasInArc(2 * M_PI - arc, target);
4119}

◆ IsInCombat()

bool Unit::IsInCombat ( ) const
inline

◆ IsInCombatWith()

bool Unit::IsInCombatWith ( Unit const *  who) const
21043{
21044 // Check target exists
21045 if (!who)
21046 return false;
21047 // Search in threat list
21048 ObjectGuid guid = who->GetGUID();
21049 for (ThreatContainer::StorageType::const_iterator i = m_ThreatMgr.GetThreatList().begin(); i != m_ThreatMgr.GetThreatList().end(); ++i)
21050 {
21051 HostileReference* ref = (*i);
21052 // Return true if the unit matches
21053 if (ref && ref->getUnitGuid() == guid)
21054 return true;
21055 }
21056 // Nothing found, false.
21057 return false;
21058}
Definition: ThreatMgr.h:49
ObjectGuid getUnitGuid() const
Definition: ThreatMgr.h:107
ThreatContainer::StorageType const & GetThreatList() const
Definition: ThreatMgr.h:271

◆ IsInDisallowedMountForm()

bool Unit::IsInDisallowedMountForm ( ) const
21245{
21246 if (SpellInfo const* transformSpellInfo = sSpellMgr->GetSpellInfo(getTransForm()))
21247 {
21248 if (transformSpellInfo->HasAttribute(SPELL_ATTR0_ALLOW_WHILE_MOUNTED))
21249 {
21250 return false;
21251 }
21252 }
21253
21254 if (ShapeshiftForm form = GetShapeshiftForm())
21255 {
21256 SpellShapeshiftEntry const* shapeshift = sSpellShapeshiftStore.LookupEntry(form);
21257 if (!shapeshift)
21258 {
21259 return true;
21260 }
21261
21262 if (!(shapeshift->flags1 & 0x1))
21263 {
21264 return true;
21265 }
21266 }
21267
21269 {
21270 return false;
21271 }
21272
21273 CreatureDisplayInfoEntry const* display = sCreatureDisplayInfoStore.LookupEntry(GetDisplayId());
21274 if (!display)
21275 {
21276 return true;
21277 }
21278
21280 if (!displayExtra)
21281 {
21282 return true;
21283 }
21284
21285 CreatureModelDataEntry const* model = sCreatureModelDataStore.LookupEntry(display->ModelId);
21286 ChrRacesEntry const* race = sChrRacesStore.LookupEntry(displayExtra->DisplayRaceID);
21287
21288 if (model && !(model->HasFlag(CREATURE_MODEL_DATA_FLAGS_CAN_MOUNT)))
21289 {
21290 if (race && !(race->HasFlag(CHRRACES_FLAGS_CAN_MOUNT)))
21291 {
21292 return true;
21293 }
21294 }
21295
21296 return false;
21297}
DBCStorage< CreatureDisplayInfoExtraEntry > sCreatureDisplayInfoExtraStore(CreatureDisplayInfoExtrafmt)
@ CHRRACES_FLAGS_CAN_MOUNT
Definition: DBCStructure.h:675
@ CREATURE_MODEL_DATA_FLAGS_CAN_MOUNT
Definition: DBCStructure.h:771
@ SPELL_ATTR0_ALLOW_WHILE_MOUNTED
Definition: SharedDefines.h:378
uint32 GetDisplayId() const
Definition: Unit.h:2163
bool HasFlag(ChrRacesFlags flag) const
Definition: DBCStructure.h:700
uint32 ExtendedDisplayInfoID
Definition: DBCStructure.h:725
Definition: DBCStructure.h:739
uint32 DisplayRaceID
Definition: DBCStructure.h:741
bool HasFlag(CreatureModelDataFlags flag) const
Definition: DBCStructure.h:795
uint32 flags1
Definition: DBCStructure.h:1783

◆ IsInFeralForm()

bool Unit::IsInFeralForm ( ) const
inline
2075 {
2077 return form == FORM_CAT || form == FORM_BEAR || form == FORM_DIREBEAR || form == FORM_GHOSTWOLF; // Xinef: added shamans Ghost Wolf, should behave exactly like druid forms
2078 }
@ FORM_GHOSTWOLF
Definition: Unit.h:106

◆ IsInFlight()

bool Unit::IsInFlight ( ) const
inline

◆ isInFrontInMap()

bool Unit::isInFrontInMap ( Unit const *  target,
float  distance,
float  arc = M_PI 
) const
4112{
4113 return IsWithinDistInMap(target, distance) && HasInArc(arc, target);
4114}

◆ IsInnkeeper()

bool Unit::IsInnkeeper ( ) const
inline
@ UNIT_NPC_FLAG_INNKEEPER
Definition: Unit.h:532

◆ IsInPartyWith()

bool Unit::IsInPartyWith ( Unit const *  unit) const
18807{
18808 if (this == unit)
18809 return true;
18810
18811 Unit const* u1 = GetCharmerOrOwnerOrSelf();
18812 Unit const* u2 = unit->GetCharmerOrOwnerOrSelf();
18813 if (u1 == u2)
18814 return true;
18815
18816 if (u1->GetTypeId() == TYPEID_PLAYER && u2->GetTypeId() == TYPEID_PLAYER)
18817 return u1->ToPlayer()->IsInSameGroupWith(u2->ToPlayer());
18818 // Xinef: we assume that npcs with the same faction are in party
18819 else if (u1->GetTypeId() == TYPEID_UNIT && u2->GetTypeId() == TYPEID_UNIT && !u1->IsControlledByPlayer() && !u2->IsControlledByPlayer())
18820 return u1->GetFaction() == u2->GetFaction();
18821 // Xinef: creature type_flag should work for party check only if player group is not a raid
18824 return true;
18825 else
18826 return false;
18827}
bool isRaidGroup() const
Definition: Group.cpp:2211
bool IsInSameGroupWith(Player const *p) const
Definition: Player.cpp:2274

◆ IsInRaidWith()

bool Unit::IsInRaidWith ( Unit const *  unit) const
18830{
18831 if (this == unit)
18832 return true;
18833
18834 Unit const* u1 = GetCharmerOrOwnerOrSelf();
18835 Unit const* u2 = unit->GetCharmerOrOwnerOrSelf();
18836 if (u1 == u2)
18837 return true;
18838
18839 if (u1->GetTypeId() == TYPEID_PLAYER && u2->GetTypeId() == TYPEID_PLAYER)
18840 return u1->ToPlayer()->IsInSameRaidWith(u2->ToPlayer());
18841 // Xinef: we assume that npcs with the same faction are in party
18842 else if (u1->GetTypeId() == TYPEID_UNIT && u2->GetTypeId() == TYPEID_UNIT && !u1->IsControlledByPlayer() && !u2->IsControlledByPlayer())
18843 return u1->GetFaction() == u2->GetFaction();
18846 return true;
18847 else
18848 return false;
18849}

◆ isInRoots()

bool Unit::isInRoots ( ) const
inline

◆ IsInSanctuary()

bool Unit::IsInSanctuary ( ) const
inline

◆ IsInWater()

bool Unit::IsInWater ( ) const
virtual

Reimplemented in Player.

4268{
4269 return (GetLiquidData().Status & MAP_LIQUID_STATUS_SWIMMING) != 0;
4270}

◆ IsLevitating()

bool Unit::IsLevitating ( ) const
inline

◆ IsMounted()

bool Unit::IsMounted ( ) const
inline
1540{ return HasUnitFlag(UNIT_FLAG_MOUNT); }

◆ IsMovementPreventedByCasting()

bool Unit::IsMovementPreventedByCasting ( ) const
virtual

Reimplemented in Creature.

4088{
4089 // can always move when not casting
4091 {
4092 return false;
4093 }
4094
4095 // channeled spells during channel stage (after the initial cast timer) allow movement with a specific spell attribute
4097 {
4098 if (spell->getState() != SPELL_STATE_FINISHED && spell->IsChannelActive())
4099 {
4100 if (spell->GetSpellInfo()->IsActionAllowedChannel())
4101 {
4102 return false;
4103 }
4104 }
4105 }
4106
4107 // prohibit movement for all other spell casts
4108 return true;
4109}
@ UNIT_STATE_CASTING
Definition: Unit.h:340

◆ isMoving()

bool Unit::isMoving ( ) const
inline
@ MOVEMENTFLAG_MASK_MOVING
Definition: Unit.h:585

◆ IsNeutralToAll()

bool Unit::IsNeutralToAll ( ) const
10221{
10222 FactionTemplateEntry const* my_faction = GetFactionTemplateEntry();
10223 if (!my_faction || !my_faction->faction)
10224 return true;
10225
10226 FactionEntry const* raw_faction = sFactionStore.LookupEntry(my_faction->faction);
10227 if (raw_faction && raw_faction->reputationListID >= 0)
10228 return false;
10229
10230 return my_faction->IsNeutralToAll();
10231}
bool IsNeutralToAll() const
Definition: DBCStructure.h:973

◆ IsNonMeleeSpellCast()

bool Unit::IsNonMeleeSpellCast ( bool  withDelayed,
bool  skipChanneled = false,
bool  skipAutorepeat = false,
bool  isAutoshoot = false,
bool  skipInstant = true 
) const
4028{
4029 // We don't do loop here to explicitly show that melee spell is excluded.
4030 // Maybe later some special spells will be excluded too.
4031
4032 // generic spells are cast when they are not finished and not delayed
4035 (withDelayed || m_currentSpells[CURRENT_GENERIC_SPELL]->getState() != SPELL_STATE_DELAYED))
4036 {
4037 if (!skipInstant || m_currentSpells[CURRENT_GENERIC_SPELL]->GetCastTime())
4038 {
4039 if (!isAutoshoot || !m_currentSpells[CURRENT_GENERIC_SPELL]->m_spellInfo->HasAttribute(SPELL_ATTR2_DO_NOT_RESET_COMBAT_TIMERS))
4040 return true;
4041 }
4042 }
4043 // channeled spells may be delayed, but they are still considered cast
4044 if (!skipChanneled && m_currentSpells[CURRENT_CHANNELED_SPELL] &&
4046 {
4047 if (!isAutoshoot || !m_currentSpells[CURRENT_CHANNELED_SPELL]->m_spellInfo->HasAttribute(SPELL_ATTR2_DO_NOT_RESET_COMBAT_TIMERS))
4048 return true;
4049 }
4050 // autorepeat spells may be finished or delayed, but they are still considered cast
4051 if (!skipAutorepeat && m_currentSpells[CURRENT_AUTOREPEAT_SPELL])
4052 return true;
4053
4054 return false;
4055}
@ SPELL_ATTR2_DO_NOT_RESET_COMBAT_TIMERS
Definition: SharedDefines.h:445

◆ IsOnVehicle()

bool Unit::IsOnVehicle ( Unit const *  vehicle) const
inline
2350{ return m_vehicle && m_vehicle == vehicle->GetVehicleKit(); }

◆ IsPet()

bool Unit::IsPet ( ) const
inline
1413{ return m_unitTypeMask & UNIT_MASK_PET; }
@ UNIT_MASK_PET
Definition: Unit.h:679

◆ IsPetAura()

bool Unit::IsPetAura ( Aura const *  aura)
17387{
17388 Unit* owner = GetOwner();
17389
17390 if (!owner || owner->GetTypeId() != TYPEID_PLAYER)
17391 return false;
17392
17393 // if the owner has that pet aura, return true
17394 for (PetAura const* petAura : owner->m_petAuras)
17395 if (petAura->GetAura(GetEntry()) == aura->GetId())
17396 return true;
17397
17398 return false;
17399}
Definition: SpellMgr.h:463
uint32 GetAura(uint32 petEntry) const
Definition: SpellMgr.h:479

◆ IsPetInCombat()

bool Unit::IsPetInCombat ( ) const
inline

◆ IsPolymorphed()

bool Unit::IsPolymorphed ( ) const
16828{
16829 uint32 transformId = getTransForm();
16830 if (!transformId)
16831 return false;
16832
16833 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(transformId);
16834 if (!spellInfo)
16835 return false;
16836
16837 return spellInfo->GetSpellSpecific() == SPELL_SPECIFIC_MAGE_POLYMORPH;
16838}
@ SPELL_SPECIFIC_MAGE_POLYMORPH
Definition: SpellInfo.h:160
SpellSpecificType GetSpellSpecific() const
Definition: SpellInfo.cpp:2117

◆ isPossessed()

bool Unit::isPossessed ( ) const
inline

◆ isPossessedByPlayer()

bool Unit::isPossessedByPlayer ( ) const
inline

◆ isPossessing() [1/2]

bool Unit::isPossessing ( ) const
inline
1872 {
1873 if (Unit* u = GetCharm())
1874 return u->isPossessed();
1875 else
1876 return false;
1877 }

◆ isPossessing() [2/2]

bool Unit::isPossessing ( Unit u) const
inline
1878{ return u->isPossessed() && GetCharmGUID() == u->GetGUID(); }
bool isPossessed() const
Definition: Unit.h:1869

◆ IsPvP()

bool Unit::IsPvP ( ) const
inline
@ UNIT_BYTE2_FLAG_PVP
Definition: Unit.h:136

◆ IsQuestGiver()

bool Unit::IsQuestGiver ( ) const
inline
@ UNIT_NPC_FLAG_QUESTGIVER
Definition: Unit.h:517

◆ IsScriptOverriden()

AuraEffect * Unit::IsScriptOverriden ( SpellInfo const *  spell,
int32  script 
) const
5710{
5712 for (AuraEffectList::const_iterator i = auras.begin(); i != auras.end(); ++i)
5713 {
5714 if ((*i)->GetMiscValue() == script)
5715 if ((*i)->IsAffectedOnSpell(spell))
5716 return (*i);
5717 }
5718 return nullptr;
5719}
@ SPELL_AURA_OVERRIDE_CLASS_SCRIPTS
Definition: SpellAuraDefines.h:175

◆ IsServiceProvider()

bool Unit::IsServiceProvider ( ) const
inline
1663 {
1664 return HasFlag(UNIT_NPC_FLAGS,
1669 }
@ UNIT_NPC_FLAG_TABARDDESIGNER
Definition: Unit.h:535
@ UNIT_NPC_FLAG_VENDOR
Definition: Unit.h:523
@ UNIT_NPC_FLAG_TRAINER
Definition: Unit.h:520
@ UNIT_NPC_FLAG_SPIRITGUIDE
Definition: Unit.h:531
@ UNIT_NPC_FLAG_SPIRITHEALER
Definition: Unit.h:530

◆ IsSitState()

bool Unit::IsSitState ( ) const
16798{
16799 uint8 s = getStandState();
16800 return
16804}
@ UNIT_STAND_STATE_SIT_HIGH_CHAIR
Definition: Unit.h:59
@ UNIT_STAND_STATE_SIT_MEDIUM_CHAIR
Definition: Unit.h:58
@ UNIT_STAND_STATE_SIT_LOW_CHAIR
Definition: Unit.h:57
@ UNIT_STAND_STATE_SIT_CHAIR
Definition: Unit.h:55

◆ isSpellBlocked()

bool Unit::isSpellBlocked ( Unit victim,
SpellInfo const *  spellProto,
WeaponAttackType  attackType = BASE_ATTACK 
)
3043{
3044 // These spells can't be blocked
3045 if (spellProto && spellProto->HasAttribute(SPELL_ATTR0_NO_ACTIVE_DEFENSE))
3046 return false;
3047
3048 if (victim->HasAuraType(SPELL_AURA_IGNORE_HIT_DIRECTION) || victim->HasInArc(M_PI, this))
3049 {
3050 // Check creatures flags_extra for disable block
3051 if (victim->GetTypeId() == TYPEID_UNIT &&
3053 return false;
3054
3055 float blockChance = victim->GetUnitBlockChance();
3056 blockChance += (int32(GetWeaponSkillValue(attackType)) - int32(victim->GetMaxSkillValueForLevel())) * 0.04f;
3057
3058 // xinef: cant block while casting or while stunned
3059 if (blockChance < 0.0f || victim->IsNonMeleeSpellCast(false, false, true) || victim->HasUnitState(UNIT_STATE_CONTROLLED))
3060 blockChance = 0.0f;
3061
3062 if (roll_chance_f(blockChance))
3063 return true;
3064 }
3065 return false;
3066}
@ CREATURE_FLAG_EXTRA_NO_BLOCK
Definition: CreatureData.h:53
@ SPELL_ATTR0_NO_ACTIVE_DEFENSE
Definition: SharedDefines.h:375
@ SPELL_AURA_IGNORE_HIT_DIRECTION
Definition: SpellAuraDefines.h:351
@ UNIT_STATE_CONTROLLED
Definition: Unit.h:365
uint32 GetWeaponSkillValue(WeaponAttackType attType, Unit const *target=nullptr) const
Definition: Unit.cpp:3731
float GetUnitBlockChance() const
Definition: Unit.cpp:3643

◆ IsSpiritGuide()

bool Unit::IsSpiritGuide ( ) const
inline

◆ IsSpiritHealer()

bool Unit::IsSpiritHealer ( ) const
inline

◆ IsSpiritService()

bool Unit::IsSpiritService ( ) const
inline

◆ IsStandState()

bool Unit::IsStandState ( ) const
16807{
16808 uint8 s = getStandState();
16810}
@ UNIT_STAND_STATE_KNEEL
Definition: Unit.h:61

◆ IsStopped()

bool Unit::IsStopped ( ) const
inline
2261{ return !(HasUnitState(UNIT_STATE_MOVING)); }
@ UNIT_STATE_MOVING
Definition: Unit.h:364

◆ IsSummon()

bool Unit::IsSummon ( ) const
inline
1410{ return m_unitTypeMask & UNIT_MASK_SUMMON; }
@ UNIT_MASK_SUMMON
Definition: Unit.h:675

◆ isSwimming()

bool Unit::isSwimming ( ) const
inline

◆ IsTabardDesigner()

bool Unit::IsTabardDesigner ( ) const
inline

◆ isTargetableForAttack()

bool Unit::isTargetableForAttack ( bool  checkFakeDeath = true,
Unit const *  byWho = nullptr 
) const
13748{
13749 if (!IsAlive())
13750 return false;
13751
13753 return false;
13754
13755 if (IsImmuneToPC() && byWho && byWho->GetCharmerOrOwnerPlayerOrPlayerItself())
13756 return false;
13757
13758 if (GetTypeId() == TYPEID_PLAYER && ToPlayer()->IsGameMaster())
13759 return false;
13760
13761 return !HasUnitState(UNIT_STATE_UNATTACKABLE) && (!checkFakeDeath || !HasUnitState(UNIT_STATE_DIED));
13762}
@ UNIT_STATE_DIED
Definition: Unit.h:325

◆ IsTaxi()

bool Unit::IsTaxi ( ) const
inline

◆ IsTotem()

bool Unit::IsTotem ( ) const
inline
1415{ return m_unitTypeMask & UNIT_MASK_TOTEM; }
@ UNIT_MASK_TOTEM
Definition: Unit.h:678

◆ IsTrainer()

bool Unit::IsTrainer ( ) const
inline

◆ IsTriggeredAtSpellProcEvent()

bool Unit::IsTriggeredAtSpellProcEvent ( Unit victim,
Aura aura,
WeaponAttackType  attType,
bool  isVictim,
bool  active,
SpellProcEventEntry const *&  spellProcEvent,
ProcEventInfo const &  eventInfo 
)
private
17474{
17475 SpellInfo const* spellProto = aura->GetSpellInfo();
17476 SpellInfo const* procSpell = eventInfo.GetSpellInfo();
17477
17478 // let the aura be handled by new proc system if it has new entry
17479 if (sSpellMgr->GetSpellProcEntry(spellProto->Id))
17480 return false;
17481
17482 // Get proc Event Entry
17483 spellProcEvent = sSpellMgr->GetSpellProcEvent(spellProto->Id);
17484
17485 // Get EventProcFlag
17486 uint32 EventProcFlag;
17487 if (spellProcEvent && spellProcEvent->procFlags) // if exist get custom spellProcEvent->procFlags
17488 EventProcFlag = spellProcEvent->procFlags;
17489 else
17490 EventProcFlag = spellProto->ProcFlags; // else get from spell proto
17491 // Continue if no trigger exist
17492 if (!EventProcFlag)
17493 return false;
17494
17495 // Additional checks for triggered spells (ignore trap casts)
17496 //if (procExtra & PROC_EX_INTERNAL_TRIGGERED && !(procFlag & PROC_FLAG_DONE_TRAP_ACTIVATION))
17497 //{
17498 // if (!spellProto->HasAttribute(SPELL_ATTR3_CAN_PROC_TRIGGERED))
17499 // return false;
17500 //}
17501
17502 // Xinef: additional check for player auras - only player spells can trigger player proc auras
17503 // Xinef: skip victim auras
17504 // Excluded player shoot spells
17505 // Excluded player item spells
17506 if (!isVictim && IsPlayer() && !(EventProcFlag & (PROC_FLAG_KILL | PROC_FLAG_DEATH)))
17507 {
17508 if (procSpell && procSpell->SpellFamilyName == SPELLFAMILY_GENERIC && procSpell->GetCategory() != 76 &&
17509 (!eventInfo.GetProcSpell() || !eventInfo.GetProcSpell()->m_CastItem) &&
17510 (!eventInfo.GetTriggerAuraSpell() || eventInfo.GetTriggerAuraSpell()->SpellFamilyName == SPELLFAMILY_GENERIC))
17511 {
17512 return false;
17513 }
17514 }
17515
17516 // Check spellProcEvent data requirements
17517 if (!sSpellMgr->IsSpellProcEventCanTriggeredBy(spellProto, spellProcEvent, EventProcFlag, eventInfo, active))
17518 return false;
17519 // In most cases req get honor or XP from kill
17520 if (EventProcFlag & PROC_FLAG_KILL && GetTypeId() == TYPEID_PLAYER)
17521 {
17522 bool allow = false;
17523
17524 if (victim)
17525 allow = ToPlayer()->isHonorOrXPTarget(victim);
17526
17527 // Shadow Word: Death - can trigger from every kill
17528 if (aura->GetId() == 32409 || aura->GetId() == 18372 || aura->GetId() == 18213)
17529 allow = true;
17530 if (!allow)
17531 return false;
17532 }
17533 // Aura added by spell can`t trigger from self (prevent drop charges/do triggers)
17534 // But except periodic and kill triggers (can triggered from self)
17535 if (procSpell && procSpell->Id == spellProto->Id
17536 && !(spellProto->ProcFlags & (PROC_FLAG_TAKEN_PERIODIC | PROC_FLAG_KILL)))
17537 return false;
17538
17539 // Check if current equipment allows aura to proc
17540 if (!isVictim && GetTypeId() == TYPEID_PLAYER && !spellProto->HasAttribute(SPELL_ATTR3_NO_PROC_EQUIP_REQUIREMENT))
17541 {
17542 Player* player = ToPlayer();
17543 if (spellProto->EquippedItemClass == ITEM_CLASS_WEAPON)
17544 {
17545 Item* item = nullptr;
17546 if (attType == BASE_ATTACK)
17548 else if (attType == OFF_ATTACK)
17550 else
17552
17553 if (player->IsInFeralForm())
17554 return false;
17555
17556 if (!item || item->IsBroken() || item->GetTemplate()->Class != ITEM_CLASS_WEAPON || !((1 << item->GetTemplate()->SubClass) & spellProto->EquippedItemSubClassMask))
17557 return false;
17558 }
17559 else if (spellProto->EquippedItemClass == ITEM_CLASS_ARMOR)
17560 {
17561 // Check if player is wearing shield
17563 if (!item || item->IsBroken() || item->GetTemplate()->Class != ITEM_CLASS_ARMOR || !((1 << item->GetTemplate()->SubClass) & spellProto->EquippedItemSubClassMask))
17564 return false;
17565 }
17566 }
17567 // Get chance from spell
17568 float chance = float(spellProto->ProcChance);
17569 // If in spellProcEvent exist custom chance, chance = spellProcEvent->customChance;
17570 if (spellProcEvent && spellProcEvent->customChance)
17571 chance = spellProcEvent->customChance;
17572 // If PPM exist calculate chance from PPM
17573 if (spellProcEvent && spellProcEvent->ppmRate != 0)
17574 {
17575 if (!isVictim)
17576 {
17577 uint32 WeaponSpeed = GetAttackTime(attType);
17578 chance = GetPPMProcChance(WeaponSpeed, spellProcEvent->ppmRate, spellProto);
17579 }
17580 else if (victim)
17581 {
17582 uint32 WeaponSpeed = victim->GetAttackTime(attType);
17583 chance = victim->GetPPMProcChance(WeaponSpeed, spellProcEvent->ppmRate, spellProto);
17584 }
17585 }
17586
17587 // Custom chances
17588 switch (spellProto->SpellFamilyName)
17589 {
17591 {
17592 // Recklessness, allow to proc only once for whirlwind
17593 if (spellProto->Id == 1719 && procSpell && procSpell->Id == 44949)
17594 return false;
17595 }
17596 }
17597
17598 if (eventInfo.GetProcChance())
17599 {
17600 chance = *eventInfo.GetProcChance();
17601 }
17602
17603 // Apply chance modifer aura
17604 if (Player* modOwner = GetSpellModOwner())
17605 {
17606 modOwner->ApplySpellMod(spellProto->Id, SPELLMOD_CHANCE_OF_SUCCESS, chance);
17607 }
17608
17609 return roll_chance_f(chance);
17610}
@ ITEM_CLASS_ARMOR
Definition: ItemTemplate.h:304
@ ITEM_CLASS_WEAPON
Definition: ItemTemplate.h:302
@ EQUIPMENT_SLOT_RANGED
Definition: Player.h:693
@ SPELL_ATTR3_NO_PROC_EQUIP_REQUIREMENT
Definition: SharedDefines.h:466
@ SPELLMOD_CHANCE_OF_SUCCESS
Definition: SpellDefines.h:95
@ PROC_FLAG_DEATH
Definition: SpellMgr.h:143
@ PROC_FLAG_TAKEN_PERIODIC
Definition: SpellMgr.h:135
@ PROC_FLAG_KILL
Definition: SpellMgr.h:108
Item * GetUseableItemByPos(uint8 bag, uint8 slot) const
Definition: Player.h:1220
bool isHonorOrXPTarget(Unit *victim) const
Definition: Player.cpp:12378
uint32 GetCategory() const
Definition: SpellInfo.cpp:863
int32 EquippedItemClass
Definition: SpellInfo.h:373
uint32 ProcFlags
Definition: SpellInfo.h:353
int32 EquippedItemSubClassMask
Definition: SpellInfo.h:374
float GetPPMProcChance(uint32 WeaponSpeed, float PPM, SpellInfo const *spellProto) const
Definition: Unit.cpp:13355
uint32 Class
Definition: ItemTemplate.h:630
uint32 SubClass
Definition: ItemTemplate.h:631

◆ isTurning()

bool Unit::isTurning ( ) const
inline
@ MOVEMENTFLAG_MASK_TURNING
Definition: Unit.h:590

◆ IsUnderLastManaUseEffect()

bool Unit::IsUnderLastManaUseEffect ( ) const
17305{
17306 return getMSTimeDiff(m_lastManaUse, GameTime::GetGameTimeMS().count()) < 5000;
17307}

◆ IsUnderWater()

bool Unit::IsUnderWater ( ) const
virtual
4273{
4275}
@ LIQUID_MAP_UNDER_WATER
Definition: Map.h:147

◆ IsValidAssistTarget()

bool Unit::IsValidAssistTarget ( Unit const *  target) const
13885{
13886 return _IsValidAssistTarget(target, nullptr);
13887}
bool _IsValidAssistTarget(Unit const *target, SpellInfo const *bySpell) const
Definition: Unit.cpp:13890

◆ IsValidAttackTarget()

bool Unit::IsValidAttackTarget ( Unit const *  target) const
13765{
13766 return _IsValidAttackTarget(target, nullptr);
13767}

◆ IsVehicle()

bool Unit::IsVehicle ( ) const
inline

◆ IsVendor()

bool Unit::IsVendor ( ) const
inline

◆ IsVisible()

bool Unit::IsVisible ( ) const
inline
@ SEC_PLAYER
Definition: Common.h:66
@ SERVERSIDE_VISIBILITY_GM
Definition: SharedDefines.h:1245
T_VALUES GetValue(FLAG_TYPE flag) const
Definition: Object.h:359

◆ IsWalking()

bool Unit::IsWalking ( ) const
inline
@ MOVEMENTFLAG_WALKING
Definition: Unit.h:560

◆ IsWithinCombatRange()

bool Unit::IsWithinCombatRange ( Unit const *  obj,
float  dist2compare 
) const
667{
668 if (!obj || !IsInMap(obj) || !InSamePhase(obj))
669 return false;
670
671 float dx = GetPositionX() - obj->GetPositionX();
672 float dy = GetPositionY() - obj->GetPositionY();
673 float dz = GetPositionZ() - obj->GetPositionZ();
674 float distsq = dx * dx + dy * dy + dz * dz;
675
676 float sizefactor = GetCombatReach() + obj->GetCombatReach();
677 float maxdist = dist2compare + sizefactor;
678
679 return distsq < maxdist * maxdist;
680}

◆ IsWithinMeleeRange()

bool Unit::IsWithinMeleeRange ( Unit const *  obj,
float  dist = 0.f 
) const
683{
684 if (!obj || !IsInMap(obj) || !InSamePhase(obj))
685 return false;
686
687 float dx = GetPositionX() - obj->GetPositionX();
688 float dy = GetPositionY() - obj->GetPositionY();
689 float dz = GetPositionZ() - obj->GetPositionZ();
690 float distsq = dx * dx + dy * dy + dz * dz;
691
692 float maxdist = dist + GetMeleeRange(obj);
693
694 return distsq < maxdist * maxdist;
695}

◆ IsWithinRange()

bool Unit::IsWithinRange ( Unit const *  obj,
float  dist 
) const
704{
705 if (!obj || !IsInMap(obj) || !InSamePhase(obj))
706 {
707 return false;
708 }
709
710 auto dx = GetPositionX() - obj->GetPositionX();
711 auto dy = GetPositionY() - obj->GetPositionY();
712 auto dz = GetPositionZ() - obj->GetPositionZ();
713 auto distsq = dx * dx + dy * dy + dz * dz;
714
715 return distsq <= dist * dist;
716}

◆ JumpTo() [1/2]

void Unit::JumpTo ( float  speedXY,
float  speedZ,
bool  forward = true 
)
19537{
19538 float angle = forward ? 0 : M_PI;
19539 if (GetTypeId() == TYPEID_UNIT)
19540 GetMotionMaster()->MoveJumpTo(angle, speedXY, speedZ);
19541 else
19542 {
19543 float vcos = cos(angle + GetOrientation());
19544 float vsin = std::sin(angle + GetOrientation());
19545
19546 WorldPacket data(SMSG_MOVE_KNOCK_BACK, (8 + 4 + 4 + 4 + 4 + 4));
19547 data << GetPackGUID();
19548 data << uint32(0); // Sequence
19549 data << float(vcos); // x direction
19550 data << float(vsin); // y direction
19551 data << float(speedXY); // Horizontal speed
19552 data << float(-speedZ); // Z Movement speed (vertical)
19553
19554 ToPlayer()->GetSession()->SendPacket(&data);
19555 }
19556}
void MoveJumpTo(float angle, float speedXY, float speedZ)
Definition: MotionMaster.cpp:511
void SendPacket(WorldPacket const *packet)
Send a packet to the client.
Definition: WorldSession.cpp:208
@ SMSG_MOVE_KNOCK_BACK
Definition: Opcodes.h:269

◆ JumpTo() [2/2]

void Unit::JumpTo ( WorldObject obj,
float  speedZ 
)
19559{
19560 float x, y, z;
19561 obj->GetContactPoint(this, x, y, z);
19562 float speedXY = GetExactDist2d(x, y) * 10.0f / speedZ;
19563 GetMotionMaster()->MoveJump(x, y, z, speedXY, speedZ);
19564}
void MoveJump(Position const &pos, float speedXY, float speedZ, uint32 id=0)
Definition: MotionMaster.h:225
void GetContactPoint(WorldObject const *obj, float &x, float &y, float &z, float distance2d=CONTACT_DISTANCE) const
Definition: Object.cpp:2688

◆ Kill()

void Unit::Kill ( Unit killer,
Unit victim,
bool  durabilityLoss = true,
WeaponAttackType  attackType = BASE_ATTACK,
SpellInfo const *  spellProto = nullptr,
Spell const *  spell = nullptr 
)
static
17753{
17754 // Prevent killing unit twice (and giving reward from kill twice)
17755 if (!victim->GetHealth())
17756 return;
17757
17758 if (killer && !killer->IsInMap(victim))
17759 killer = nullptr;
17760
17761 // find player: owner of controlled `this` or `this` itself maybe
17762 Player* player = killer ? killer->GetCharmerOrOwnerPlayerOrPlayerItself() : nullptr;
17763 Creature* creature = victim->ToCreature();
17764
17765 bool isRewardAllowed = true;
17766 if (creature)
17767 {
17768 isRewardAllowed = creature->IsDamageEnoughForLootingAndReward();
17769 if (!isRewardAllowed)
17770 creature->SetLootRecipient(nullptr);
17771 }
17772
17773 // pussywizard: remade this if section (player is on the same map
17774 if (isRewardAllowed && creature)
17775 {
17776 Player* lr = creature->GetLootRecipient();
17777 if (lr && lr->IsInMap(creature))
17778 player = creature->GetLootRecipient();
17779 else if (Group* lrg = creature->GetLootRecipientGroup())
17780 for (GroupReference* itr = lrg->GetFirstMember(); itr != nullptr; itr = itr->next())
17781 if (Player* member = itr->GetSource())
17782 if (member->IsAtLootRewardDistance(creature))
17783 {
17784 player = member;
17785 break;
17786 }
17787 }
17788
17789 // Exploit fix
17790 if (creature && creature->IsPet() && creature->GetOwnerGUID().IsPlayer())
17791 isRewardAllowed = false;
17792
17793 // Reward player, his pets, and group/raid members
17794 // call kill spell proc event (before real die and combat stop to triggering auras removed at death/combat stop)
17795 if (isRewardAllowed && player && player != victim)
17796 {
17797 WorldPacket data(SMSG_PARTYKILLLOG, (8 + 8)); // send event PARTY_KILL
17798 data << player->GetGUID(); // player with killing blow
17799 data << victim->GetGUID(); // victim
17800
17801 Player* looter = player;
17802 Group* group = player->GetGroup();
17803 bool hasLooterGuid = false;
17804
17805 if (group)
17806 {
17807 group->BroadcastPacket(&data, group->GetMemberGroup(player->GetGUID()));
17808
17809 if (creature)
17810 {
17811 group->UpdateLooterGuid(creature, true);
17812 if (group->GetLooterGuid() && group->GetLootMethod() != FREE_FOR_ALL)
17813 {
17814 looter = ObjectAccessor::FindPlayer(group->GetLooterGuid());
17815 if (looter)
17816 {
17817 hasLooterGuid = true;
17818 creature->SetLootRecipient(looter); // update creature loot recipient to the allowed looter.
17819 }
17820 }
17821 }
17822 }
17823 else
17824 {
17825 player->SendDirectMessage(&data);
17826
17827 if (creature)
17828 {
17829 WorldPacket data2(SMSG_LOOT_LIST, 8 + 1 + 1);
17830 data2 << creature->GetGUID();
17831 data2 << uint8(0); // unk1
17832 data2 << uint8(0); // no group looter
17833 player->SendMessageToSet(&data2, true);
17834 }
17835 }
17836
17837 // Generate loot before updating looter
17838 if (creature)
17839 {
17840 Loot* loot = &creature->loot;
17841 loot->clear();
17842
17843 if (uint32 lootid = creature->GetCreatureTemplate()->lootid)
17844 loot->FillLoot(lootid, LootTemplates_Creature, looter, false, false, creature->GetLootMode(), creature);
17845
17846 if (creature->GetLootMode())
17848
17849 if (group)
17850 {
17851 if (hasLooterGuid)
17852 group->SendLooter(creature, looter);
17853 else
17854 group->SendLooter(creature, nullptr);
17855
17856 // Update round robin looter only if the creature had loot
17857 if (!creature->loot.empty())
17858 group->UpdateLooterGuid(creature);
17859 }
17860 }
17861
17862 player->RewardPlayerAndGroupAtKill(victim, false);
17863 }
17864
17865 // Do KILL and KILLED procs. KILL proc is called only for the unit who landed the killing blow (and its owner - for pets and totems) regardless of who tapped the victim
17866 if (killer && (killer->IsPet() || killer->IsTotem()))
17867 if (Unit* owner = killer->GetOwner())
17868 {
17869 Unit::ProcDamageAndSpell(owner, victim, PROC_FLAG_KILL, PROC_FLAG_NONE, PROC_EX_NONE, 0, attackType, spellProto, nullptr, -1, spell);
17870 sScriptMgr->OnCreatureKilledByPet( killer->GetCharmerOrOwnerPlayerOrPlayerItself(), victim->ToCreature());
17871 }
17872
17873 if (killer != victim && !victim->IsCritter())
17874 Unit::ProcDamageAndSpell(killer, victim, killer ? PROC_FLAG_KILL : 0, PROC_FLAG_KILLED, PROC_EX_NONE, 0, attackType, spellProto, nullptr, -1, spell);
17875
17876 // Proc auras on death - must be before aura/combat remove
17877 Unit::ProcDamageAndSpell(victim, nullptr, PROC_FLAG_DEATH, PROC_FLAG_NONE, PROC_EX_NONE, 0, attackType, spellProto, nullptr, -1, spell);
17878
17879 // update get killing blow achievements, must be done before setDeathState to be able to require auras on target
17880 // and before Spirit of Redemption as it also removes auras
17881 if (killer)
17882 if (Player* killerPlayer = killer->GetCharmerOrOwnerPlayerOrPlayerItself())
17883 killerPlayer->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_GET_KILLING_BLOWS, 1, 0, victim);
17884
17885 // Spirit of Redemption
17886 // if talent known but not triggered (check priest class for speedup check)
17887 bool spiritOfRedemption = false;
17888 if (victim->GetTypeId() == TYPEID_PLAYER && victim->getClass() == CLASS_PRIEST && !victim->ToPlayer()->HasPlayerFlag(PLAYER_FLAGS_IS_OUT_OF_BOUNDS))
17889 {
17890 if (AuraEffect* aurEff = victim->GetAuraEffectDummy(20711))
17891 {
17892 // Xinef: aura_spirit_of_redemption is triggered by 27827 shapeshift
17893 if (victim->HasAuraType(SPELL_AURA_SPIRIT_OF_REDEMPTION) || victim->HasAura(27827))
17894 {
17895 /*LOG_INFO("misc", "Player ({}) died with spirit of redemption. Killer (Entry: {}, Name: {}), Map: {}, x: {}, y: {}, z: {}",
17896 victim->GetGUID().ToString(), killer ? killer->GetEntry() : 1, killer ? killer->GetName() : "", victim->GetMapId(), victim->GetPositionX(),
17897 victim->GetPositionY(), victim->GetPositionZ());
17898
17899 ACE_Stack_Trace trace(0, 50);
17900 LOG_INFO("misc", "TRACE: {}\n\n", trace);*/
17901 }
17902 else
17903 {
17904 // save value before aura remove
17905 uint32 ressSpellId = victim->GetUInt32Value(PLAYER_SELF_RES_SPELL);
17906 if (!ressSpellId)
17907 ressSpellId = victim->ToPlayer()->GetResurrectionSpellId();
17908
17909 //Remove all expected to remove at death auras (most important negative case like DoT or periodic triggers)
17910 victim->RemoveAllAurasOnDeath();
17911
17912 // Stop attacks
17913 victim->CombatStop();
17915
17916 // restore for use at real death
17917 victim->SetUInt32Value(PLAYER_SELF_RES_SPELL, ressSpellId);
17918
17919 // FORM_SPIRITOFREDEMPTION and related auras
17920 victim->CastSpell(victim, 27827, true, nullptr, aurEff);
17921 spiritOfRedemption = true;
17922 }
17923 }
17924 }
17925
17926 if (!spiritOfRedemption)
17927 {
17928 LOG_DEBUG("entities.unit", "SET JUST_DIED");
17929 victim->setDeathState(JUST_DIED);
17930 }
17931
17932 // Inform pets (if any) when player kills target)
17933 // MUST come after victim->setDeathState(JUST_DIED); or pet next target
17934 // selection will get stuck on same target and break pet react state
17935 if (player)
17936 {
17937 Pet* pet = player->GetPet();
17938 if (pet && pet->IsAlive() && pet->isControlled())
17939 pet->AI()->KilledUnit(victim);
17940 }
17941
17942 // 10% durability loss on death
17943 // clean InHateListOf
17944 if (Player* plrVictim = victim->ToPlayer())
17945 {
17946 // remember victim PvP death for corpse type and corpse reclaim delay
17947 // at original death (not at SpiritOfRedemtionTalent timeout)
17948 plrVictim->SetPvPDeath(player != nullptr);
17949
17950 // only if not player and not controlled by player pet. And not at BG
17951 if ((durabilityLoss && !player && !plrVictim->InBattleground()) || (player && sWorld->getBoolConfig(CONFIG_DURABILITY_LOSS_IN_PVP)))
17952 {
17953 LOG_DEBUG("entities.unit", "We are dead, losing {} percent durability", sWorld->getRate(RATE_DURABILITY_LOSS_ON_DEATH));
17954 plrVictim->DurabilityLossAll(sWorld->getRate(RATE_DURABILITY_LOSS_ON_DEATH), false);
17955 // durability lost message
17956 plrVictim->SendDurabilityLoss();
17957 }
17958 // Call KilledUnit for creatures
17959 if (killer && killer->GetTypeId() == TYPEID_UNIT && killer->IsAIEnabled)
17960 killer->ToCreature()->AI()->KilledUnit(victim);
17961
17962 // last damage from non duel opponent or opponent controlled creature
17963 if (plrVictim->duel)
17964 {
17965 plrVictim->duel->Opponent->CombatStopWithPets(true);
17966 plrVictim->CombatStopWithPets(true);
17967 plrVictim->DuelComplete(DUEL_INTERRUPTED);
17968 }
17969 }
17970 else // creature died
17971 {
17972 LOG_DEBUG("entities.unit", "DealDamageNotPlayer");
17973
17974 if (!creature->IsPet() && creature->GetLootMode() > 0)
17975 {
17976 creature->GetThreatMgr().ClearAllThreat();
17977
17978 // must be after setDeathState which resets dynamic flags
17979 if (!creature->loot.isLooted())
17980 {
17982 }
17983 else
17984 {
17985 creature->AllLootRemovedFromCorpse();
17986 }
17987 }
17988
17989 // Call KilledUnit for creatures, this needs to be called after the lootable flag is set
17990 if (killer && killer->GetTypeId() == TYPEID_UNIT && killer->IsAIEnabled)
17991 killer->ToCreature()->AI()->KilledUnit(victim);
17992
17993 // Call creature just died function
17994 if (CreatureAI* ai = creature->AI())
17995 {
17996 ai->JustDied(killer);
17997 sScriptMgr->OnUnitDeath(creature, killer);
17998 }
17999
18000 if (TempSummon* summon = creature->ToTempSummon())
18001 if (Unit* summoner = summon->GetSummonerUnit())
18002 if (summoner->ToCreature() && summoner->IsAIEnabled)
18003 summoner->ToCreature()->AI()->SummonedCreatureDies(creature, killer);
18004
18005 // Dungeon specific stuff, only applies to players killing creatures
18006 if (creature->GetInstanceId())
18007 {
18008 Map* instanceMap = creature->GetMap();
18009 //Player* creditedPlayer = GetCharmerOrOwnerPlayerOrPlayerItself();
18010 // TODO: do instance binding anyway if the charmer/owner is offline
18011
18012 if (instanceMap->IsDungeon() && player)
18013 if (instanceMap->IsRaidOrHeroicDungeon())
18015 instanceMap->ToInstanceMap()->PermBindAllPlayers();
18016 }
18017 }
18018
18019 // outdoor pvp things, do these after setting the death state, else the player activity notify won't work... doh...
18020 // handle player kill only if not suicide (spirit of redemption for example)
18021 if (player && killer != victim)
18022 {
18023 if (OutdoorPvP* pvp = player->GetOutdoorPvP())
18024 pvp->HandleKill(player, victim);
18025
18026 if (Battlefield* bf = sBattlefieldMgr->GetBattlefieldToZoneId(player->GetZoneId()))
18027 bf->HandleKill(player, victim);
18028 }
18029
18030 //if (victim->GetTypeId() == TYPEID_PLAYER)
18031 // if (OutdoorPvP* pvp = victim->ToPlayer()->GetOutdoorPvP())
18032 // pvp->HandlePlayerActivityChangedpVictim->ToPlayer();
18033
18034 // battleground things (do this at the end, so the death state flag will be properly set to handle in the bg->handlekill)
18035 if (player)
18036 if (Battleground* bg = player->GetBattleground())
18037 {
18038 if (victim->GetTypeId() == TYPEID_PLAYER)
18039 bg->HandleKillPlayer(victim->ToPlayer(), player);
18040 else
18041 bg->HandleKillUnit(victim->ToCreature(), player);
18042 }
18043
18044 // achievement stuff
18045 if (killer && victim->GetTypeId() == TYPEID_PLAYER)
18046 {
18047 if (killer->GetTypeId() == TYPEID_UNIT)
18049 else if (victim != killer && killer->GetTypeId() == TYPEID_PLAYER)
18051 }
18052
18053 // Hook for OnPVPKill Event
18054 if (killer)
18055 {
18056 if (Player* killerPlr = killer->ToPlayer())
18057 {
18058 if (Player* killedPlr = victim->ToPlayer())
18059 sScriptMgr->OnPVPKill(killerPlr, killedPlr);
18060 else if (Creature* killedCre = victim->ToCreature())
18061 sScriptMgr->OnCreatureKill(killerPlr, killedCre);
18062 }
18063 else if (Creature* killerCre = killer->ToCreature())
18064 {
18065 if (Player* killed = victim->ToPlayer())
18066 sScriptMgr->OnPlayerKilledByCreature(killerCre, killed);
18067 }
18068 }
18069}
#define sBattlefieldMgr
Definition: BattlefieldMgr.h:77
@ CREATURE_FLAG_EXTRA_INSTANCE_BIND
Definition: CreatureData.h:49
@ ACHIEVEMENT_CRITERIA_TYPE_KILLED_BY_PLAYER
Definition: DBCEnums.h:144
@ ACHIEVEMENT_CRITERIA_TYPE_KILLED_BY_CREATURE
Definition: DBCEnums.h:143
@ ACHIEVEMENT_CRITERIA_TYPE_GET_KILLING_BLOWS
Definition: DBCEnums.h:176
@ CONFIG_DURABILITY_LOSS_IN_PVP
Definition: IWorld.h:71
@ RATE_DURABILITY_LOSS_ON_DEATH
Definition: IWorld.h:499
LootStore LootTemplates_Creature("creature_loot_template", "creature entry", true)
@ FREE_FOR_ALL
Definition: LootMgr.h:59
@ PLAYER_FLAGS_IS_OUT_OF_BOUNDS
Definition: Player.h:489
@ DUEL_INTERRUPTED
Definition: SharedDefines.h:3584
@ PROC_FLAG_KILLED
Definition: SpellMgr.h:107
@ PLAYER_SELF_RES_SPELL
Definition: UpdateFields.h:370
Definition: Battlefield.h:205
Definition: CreatureAI.h:70
virtual void KilledUnit(Unit *)
Definition: CreatureAI.h:125
Loot loot
Definition: Creature.h:217
uint16 GetLootMode() const
Definition: Creature.h:231
void AllLootRemovedFromCorpse()
Definition: Creature.cpp:2864
Player * GetLootRecipient() const
Definition: Creature.cpp:1262
bool IsDamageEnoughForLootingAndReward() const
Definition: Creature.cpp:3651
Group * GetLootRecipientGroup() const
Definition: Creature.cpp:1269
void BroadcastPacket(WorldPacket const *packet, bool ignorePlayersInBGRaid, int group=-1, ObjectGuid ignore=ObjectGuid::Empty)
Definition: Group.cpp:1726
uint8 GetMemberGroup(ObjectGuid guid) const
Definition: Group.cpp:2319
ObjectGuid GetLooterGuid() const
Definition: Group.cpp:2256
LootMethod GetLootMethod() const
Definition: Group.cpp:2251
void UpdateLooterGuid(WorldObject *pLootedObject, bool ifneed=false)
Definition: Group.cpp:1837
void SendLooter(Creature *creature, Player *pLooter)
Definition: Group.cpp:967
void PermBindAllPlayers()
Definition: Map.cpp:3128
Definition: Map.h:312
bool IsRaidOrHeroicDungeon() const
Definition: Map.h:450
InstanceMap * ToInstanceMap()
Definition: Map.h:544
virtual void SetDynamicFlag(uint32 flag)
Definition: Object.h:117
Definition: OutdoorPvP.h:187
void SendDirectMessage(WorldPacket const *data) const
Definition: Player.cpp:5578
TeamId GetTeamId(bool original=false) const
Definition: Player.h:2058
Battleground * GetBattleground(bool create=false) const
Definition: Player.cpp:11913
uint32 GetResurrectionSpellId()
Definition: Player.cpp:12321
OutdoorPvP * GetOutdoorPvP() const
Definition: Player.cpp:12222
void RewardPlayerAndGroupAtKill(Unit *victim, bool isBattleGround)
Definition: Player.cpp:12438
Definition: TemporarySummon.h:40
void RemoveAllAurasOnDeath()
Definition: Unit.cpp:5257
AuraEffect * GetAuraEffectDummy(uint32 spellid) const
Definition: Unit.cpp:5456
bool IsCritter() const
Definition: Unit.h:1671
uint32 GetInstanceId() const
Definition: Object.h:431
uint32 GetZoneId() const
Definition: Object.cpp:3058
@ SMSG_PARTYKILLLOG
Definition: Opcodes.h:531
@ SMSG_LOOT_LIST
Definition: Opcodes.h:1047
Player * FindPlayer(ObjectGuid const guid)
Definition: ObjectAccessor.cpp:250
uint32 mingold
Definition: CreatureData.h:224
uint32 maxgold
Definition: CreatureData.h:225
uint32 lootid
Definition: CreatureData.h:217
Definition: LootMgr.h:313
bool empty() const
Definition: LootMgr.h:367
bool isLooted() const
Definition: LootMgr.h:368
void clear()
Definition: LootMgr.h:343
void generateMoneyLoot(uint32 minAmount, uint32 maxAmount)
Definition: LootMgr.cpp:793
bool FillLoot(uint32 lootId, LootStore const &store, Player *lootOwner, bool personal, bool noEmptyError=false, uint16 lootMode=LOOT_MODE_DEFAULT, WorldObject *lootSource=nullptr)
Definition: LootMgr.cpp:544

◆ KnockbackFrom()

void Unit::KnockbackFrom ( float  x,
float  y,
float  speedXY,
float  speedZ 
)
19176{
19177 Player* player = ToPlayer();
19178 if (!player)
19179 {
19180 if (Unit* charmer = GetCharmer())
19181 {
19182 player = charmer->ToPlayer();
19183 if (player && player->m_mover != this)
19184 player = nullptr;
19185 }
19186 }
19187
19188 if (!player)
19189 {
19190 GetMotionMaster()->MoveKnockbackFrom(x, y, speedXY, speedZ);
19191 }
19192 else
19193 {
19194 float vcos, vsin;
19195 GetSinCos(x, y, vsin, vcos);
19196
19197 WorldPacket data(SMSG_MOVE_KNOCK_BACK, (8 + 4 + 4 + 4 + 4 + 4));
19198 data << GetPackGUID();
19199 data << uint32(0); // counter
19200 data << float(vcos); // x direction
19201 data << float(vsin); // y direction
19202 data << float(speedXY); // Horizontal speed
19203 data << float(-speedZ); // Z Movement speed (vertical)
19204
19205 player->GetSession()->SendPacket(&data);
19206
19208 player->SetCanFly(true, true);
19209
19210 sScriptMgr->AnticheatSetSkipOnePacketForASH(player, true);
19211 player->SetCanKnockback(true);
19212 }
19213}
@ SPELL_AURA_FLY
Definition: SpellAuraDefines.h:264
@ SPELL_AURA_MOD_INCREASE_MOUNTED_FLIGHT_SPEED
Definition: SpellAuraDefines.h:270
void MoveKnockbackFrom(float srcX, float srcY, float speedXY, float speedZ)
Definition: MotionMaster.cpp:485
SafeUnitPointer m_mover
Definition: Player.h:2281
void SetCanKnockback(bool value)
Definition: Player.h:2449
bool SetCanFly(bool apply, bool packetOnly=false) override
Definition: Player.cpp:15609
void GetSinCos(float x, float y, float &vsin, float &vcos) const
Definition: Position.cpp:91

◆ MagicSpellHitResult()

SpellMissInfo Unit::MagicSpellHitResult ( Unit victim,
SpellInfo const *  spell 
)
3270{
3271 // Can`t miss on dead target (on skinning for example)
3272 if (!victim->IsAlive() && victim->GetTypeId() != TYPEID_PLAYER)
3273 return SPELL_MISS_NONE;
3274
3275 // vehicles cant miss
3276 if (IsVehicle())
3277 return SPELL_MISS_NONE;
3278
3279 // Spells with SPELL_ATTR3_ALWAYS_HIT will additionally fully ignore
3280 // resist and deflect chances
3281 // xinef: skip all calculations, proof: Toxic Tolerance quest
3282 if (spellInfo->HasAttribute(SPELL_ATTR3_ALWAYS_HIT))
3283 return SPELL_MISS_NONE;
3284
3285 if (spellInfo->HasAttribute(SPELL_ATTR7_NO_ATTACK_MISS))
3286 {
3287 return SPELL_MISS_NONE;
3288 }
3289
3290 SpellSchoolMask schoolMask = spellInfo->GetSchoolMask();
3291 int32 thisLevel = getLevelForTarget(victim);
3292 if (GetTypeId() == TYPEID_UNIT && ToCreature()->IsTrigger())
3293 thisLevel = std::max<int32>(thisLevel, spellInfo->SpellLevel);
3294 int32 levelDiff = int32(victim->getLevelForTarget(this)) - thisLevel;
3295
3296 int32 MISS_CHANCE_MULTIPLIER;
3297 if (sWorld->getBoolConfig(CONFIG_MISS_CHANCE_MULTIPLIER_ONLY_FOR_PLAYERS) && GetTypeId() != TYPEID_PLAYER) // keep it as it was originally (7 and 11)
3298 {
3299 MISS_CHANCE_MULTIPLIER = victim->GetTypeId() == TYPEID_PLAYER ? 7 : 11;
3300 }
3301 else
3302 {
3303 MISS_CHANCE_MULTIPLIER = sWorld->getRate(
3304 victim->GetTypeId() == TYPEID_PLAYER
3307 }
3308
3309 // Base hit chance from attacker and victim levels
3310 int32 modHitChance = levelDiff < 3
3311 ? 96 - levelDiff
3312 : 94 - (levelDiff - 2) * MISS_CHANCE_MULTIPLIER;
3313
3314 // Spellmod from SPELLMOD_RESIST_MISS_CHANCE
3315 if (Player* modOwner = GetSpellModOwner())
3316 modOwner->ApplySpellMod(spellInfo->Id, SPELLMOD_RESIST_MISS_CHANCE, modHitChance);
3317
3318 // Increase from attacker SPELL_AURA_MOD_INCREASES_SPELL_PCT_TO_HIT auras
3320
3321 // Spells with SPELL_ATTR3_ALWAYS_HIT will ignore target's avoidance effects
3322 // xinef: imo it should completly ignore all calculations, eg: 14792. Hits 80 level players on blizz without any problems
3323 //if (!spell->HasAttribute(SPELL_ATTR3_ALWAYS_HIT))
3324 {
3325 // Chance hit from victim SPELL_AURA_MOD_ATTACKER_SPELL_HIT_CHANCE auras
3327 // Reduce spell hit chance for Area of effect spells from victim SPELL_AURA_MOD_AOE_AVOIDANCE aura
3328 if (spellInfo->IsAffectingArea())
3329 modHitChance -= victim->GetTotalAuraModifier(SPELL_AURA_MOD_AOE_AVOIDANCE);
3330
3331 // Decrease hit chance from victim rating bonus
3332 if (victim->GetTypeId() == TYPEID_PLAYER)
3333 modHitChance -= int32(victim->ToPlayer()->GetRatingBonusValue(CR_HIT_TAKEN_SPELL));
3334 }
3335
3336 int32 HitChance = modHitChance * 100;
3337 // Increase hit chance from attacker SPELL_AURA_MOD_SPELL_HIT_CHANCE and attacker ratings
3338 // Xinef: Totems should inherit casters ratings?
3339 if (IsTotem())
3340 {
3341 if (Unit* owner = GetOwner())
3342 HitChance += int32(owner->m_modSpellHitChance * 100.0f);
3343 }
3344 else
3345 HitChance += int32(m_modSpellHitChance * 100.0f);
3346
3347 if (HitChance < 100)
3348 HitChance = 100;
3349 else if (HitChance > 10000)
3350 HitChance = 10000;
3351
3352 int32 tmp = 10000 - HitChance;
3353
3354 int32 rand = irand(1, 10000); // Needs to be 1 to 10000 to avoid the 1/10000 chance to miss on 100% hit rating
3355
3356 if (rand < tmp)
3357 return SPELL_MISS_MISS;
3358
3359 // Chance resist mechanic (select max value from every mechanic spell effect)
3360 int32 resist_chance = victim->GetMechanicResistChance(spellInfo) * 100;
3361 tmp += resist_chance;
3362
3363 // Chance resist debuff
3364 if (!spellInfo->IsPositive() && !spellInfo->HasAttribute(SPELL_ATTR4_NO_CAST_LOG))
3365 {
3366 bool bNegativeAura = true;
3367 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
3368 {
3369 // Xinef: Check if effect exists!
3370 if (spellInfo->Effects[i].IsEffect() && spellInfo->Effects[i].ApplyAuraName == 0)
3371 {
3372 bNegativeAura = false;
3373 break;
3374 }
3375 }
3376
3377 if (bNegativeAura)
3378 {
3379 tmp += victim->GetMaxPositiveAuraModifierByMiscValue(SPELL_AURA_MOD_DEBUFF_RESISTANCE, int32(spellInfo->Dispel)) * 100;
3380 tmp += victim->GetMaxNegativeAuraModifierByMiscValue(SPELL_AURA_MOD_DEBUFF_RESISTANCE, int32(spellInfo->Dispel)) * 100;
3381 }
3382
3383 // Players resistance for binary spells
3384 if (spellInfo->HasAttribute(SPELL_ATTR0_CU_BINARY_SPELL) && (spellInfo->GetSchoolMask() & (SPELL_SCHOOL_MASK_NORMAL | SPELL_SCHOOL_MASK_HOLY)) == 0)
3385 tmp += int32(Unit::GetEffectiveResistChance(this, spellInfo->GetSchoolMask(), victim) * 10000.0f); // 100 for spell calculations, and 100 for return value percentage
3386 }
3387
3388 // Roll chance
3389 if (rand < tmp)
3390 return SPELL_MISS_RESIST;
3391
3392 // cast by caster in front of victim
3393 if (!victim->HasUnitState(UNIT_STATE_STUNNED) && (victim->HasInArc(M_PI, this) || victim->HasAuraType(SPELL_AURA_IGNORE_HIT_DIRECTION)))
3394 {
3395 int32 deflect_chance = victim->GetTotalAuraModifier(SPELL_AURA_DEFLECT_SPELLS) * 100;
3396 tmp += deflect_chance;
3397 if (rand < tmp)
3398 return SPELL_MISS_DEFLECT;
3399 }
3400
3401 return SPELL_MISS_NONE;
3402}
@ CONFIG_MISS_CHANCE_MULTIPLIER_ONLY_FOR_PLAYERS
Definition: IWorld.h:175
@ RATE_MISS_CHANCE_MULTIPLIER_TARGET_PLAYER
Definition: IWorld.h:506
@ RATE_MISS_CHANCE_MULTIPLIER_TARGET_CREATURE
Definition: IWorld.h:505
@ SPELL_ATTR7_NO_ATTACK_MISS
Definition: SharedDefines.h:638
@ SPELL_MISS_NONE
Definition: SharedDefines.h:1491
@ SPELL_MISS_RESIST
Definition: SharedDefines.h:1493
@ SPELL_MISS_MISS
Definition: SharedDefines.h:1492
@ SPELL_MISS_DEFLECT
Definition: SharedDefines.h:1500
@ SPELL_AURA_MOD_DEBUFF_RESISTANCE
Definition: SpellAuraDefines.h:241
@ SPELL_AURA_DEFLECT_SPELLS
Definition: SpellAuraDefines.h:350
@ SPELL_AURA_MOD_INCREASES_SPELL_PCT_TO_HIT
Definition: SpellAuraDefines.h:262
@ SPELL_AURA_MOD_ATTACKER_SPELL_HIT_CHANCE
Definition: SpellAuraDefines.h:249
@ SPELL_AURA_MOD_AOE_AVOIDANCE
Definition: SpellAuraDefines.h:223
@ SPELLMOD_RESIST_MISS_CHANCE
Definition: SpellDefines.h:93
@ CR_HIT_TAKEN_SPELL
Definition: Unit.h:417
float GetRatingBonusValue(CombatRating cr) const
Definition: Player.cpp:5084
int32 GetMaxNegativeAuraModifierByMiscValue(AuraType auratype, int32 misc_value) const
Definition: Unit.cpp:5952
int32 GetMaxPositiveAuraModifierByMiscValue(AuraType auratype, int32 misc_value) const
Definition: Unit.cpp:5938
int32 GetMechanicResistChance(SpellInfo const *spell)
Definition: Unit.cpp:3075

◆ MeleeDamageBonusDone()

uint32 Unit::MeleeDamageBonusDone ( Unit pVictim,
uint32  damage,
WeaponAttackType  attType,
SpellInfo const *  spellProto = nullptr,
SpellSchoolMask  damageSchoolMask = SPELL_SCHOOL_MASK_NORMAL 
)
12979{
12980 if (!victim || pdamage == 0)
12981 return 0;
12982
12983 if (GetTypeId() == TYPEID_UNIT)
12984 {
12985 // Dancing Rune Weapon...
12986 if (GetEntry() == 27893)
12987 {
12988 if (Unit* owner = GetOwner())
12989 return owner->MeleeDamageBonusDone(victim, pdamage, attType, spellProto, damageSchoolMask) / 2;
12990 }
12991 }
12992
12993 uint32 creatureTypeMask = victim->GetCreatureTypeMask();
12994
12995 // Done fixed damage bonus auras
12996 int32 DoneFlatBenefit = 0;
12997
12998 // ..done
13000 for (AuraEffectList::const_iterator i = mDamageDoneCreature.begin(); i != mDamageDoneCreature.end(); ++i)
13001 if (creatureTypeMask & uint32((*i)->GetMiscValue()))
13002 DoneFlatBenefit += (*i)->GetAmount();
13003
13004 // ..done
13005 // SPELL_AURA_MOD_DAMAGE_DONE included in weapon damage
13006
13007 // ..done (base at attack power for marked target and base at attack power for creature type)
13008 int32 APbonus = 0;
13009
13010 if (attType == RANGED_ATTACK)
13011 {
13012 APbonus += victim->GetTotalAuraModifier(SPELL_AURA_RANGED_ATTACK_POWER_ATTACKER_BONUS);
13013
13014 // ..done (base at attack power and creature type)
13016 for (AuraEffectList::const_iterator i = mCreatureAttackPower.begin(); i != mCreatureAttackPower.end(); ++i)
13017 if (creatureTypeMask & uint32((*i)->GetMiscValue()))
13018 APbonus += (*i)->GetAmount();
13019 }
13020 else
13021 {
13022 APbonus += victim->GetTotalAuraModifier(SPELL_AURA_MELEE_ATTACK_POWER_ATTACKER_BONUS);
13023
13024 // ..done (base at attack power and creature type)
13026 for (AuraEffectList::const_iterator i = mCreatureAttackPower.begin(); i != mCreatureAttackPower.end(); ++i)
13027 if (creatureTypeMask & uint32((*i)->GetMiscValue()))
13028 APbonus += (*i)->GetAmount();
13029 }
13030
13031 if (APbonus != 0) // Can be negative
13032 {
13033 bool normalized = false;
13034 if (spellProto)
13035 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
13036 if (spellProto->Effects[i].Effect == SPELL_EFFECT_NORMALIZED_WEAPON_DMG)
13037 {
13038 normalized = true;
13039 break;
13040 }
13041 DoneFlatBenefit += int32(APbonus / 14.0f * GetAPMultiplier(attType, normalized));
13042 }
13043
13044 // Done total percent damage auras
13045 float DoneTotalMod = 1.0f;
13046
13047 // mods for SPELL_SCHOOL_MASK_NORMAL are already factored in base melee damage calculation
13048 if (!(damageSchoolMask & SPELL_SCHOOL_MASK_NORMAL))
13049 {
13050 // Some spells don't benefit from pct done mods
13052 for (AuraEffectList::const_iterator i = mModDamagePercentDone.begin(); i != mModDamagePercentDone.end(); ++i)
13053 {
13054 if (!spellProto || (spellProto->ValidateAttribute6SpellDamageMods(this, *i, false) &&
13055 sScriptMgr->IsNeedModMeleeDamagePercent(this, *i, DoneTotalMod, spellProto)))
13056 {
13057 if (((*i)->GetMiscValue() & damageSchoolMask))
13058 {
13059 if ((*i)->GetSpellInfo()->EquippedItemClass == -1)
13060 AddPct(DoneTotalMod, (*i)->GetAmount());
13061 else if (!(*i)->GetSpellInfo()->HasAttribute(SPELL_ATTR5_AURA_AFFECTS_NOT_JUST_REQ_EQUIPED_ITEM) && ((*i)->GetSpellInfo()->EquippedItemSubClassMask == 0))
13062 AddPct(DoneTotalMod, (*i)->GetAmount());
13063 else if (ToPlayer() && ToPlayer()->HasItemFitToSpellRequirements((*i)->GetSpellInfo()))
13064 AddPct(DoneTotalMod, (*i)->GetAmount());
13065 }
13066 }
13067 }
13068 }
13069
13071 for (AuraEffectList::const_iterator i = mDamageDoneVersus.begin(); i != mDamageDoneVersus.end(); ++i)
13072 if (creatureTypeMask & uint32((*i)->GetMiscValue()))
13073 if (!spellProto || spellProto->ValidateAttribute6SpellDamageMods(this, *i, false))
13074 AddPct(DoneTotalMod, (*i)->GetAmount());
13075
13076 // bonus against aurastate
13078 for (AuraEffectList::const_iterator i = mDamageDoneVersusAurastate.begin(); i != mDamageDoneVersusAurastate.end(); ++i)
13079 if (victim->HasAuraState(AuraStateType((*i)->GetMiscValue())))
13080 if (!spellProto || spellProto->ValidateAttribute6SpellDamageMods(this, *i, false))
13081 AddPct(DoneTotalMod, (*i)->GetAmount());
13082
13083 // done scripted mod (take it from owner)
13084 Unit* owner = GetOwner() ? GetOwner() : this;
13085 AuraEffectList const& mOverrideClassScript = owner->GetAuraEffectsByType(SPELL_AURA_OVERRIDE_CLASS_SCRIPTS);
13086 for (AuraEffectList::const_iterator i = mOverrideClassScript.begin(); i != mOverrideClassScript.end(); ++i)
13087 {
13088 if (spellProto && !spellProto->ValidateAttribute6SpellDamageMods(this, *i, false))
13089 continue;
13090
13091 if (!(*i)->IsAffectedOnSpell(spellProto))
13092 continue;
13093
13094 switch ((*i)->GetMiscValue())
13095 {
13096 // Tundra Stalker
13097 // Merciless Combat
13098 case 7277:
13099 {
13100 // Merciless Combat
13101 if ((*i)->GetSpellInfo()->SpellIconID == 2656)
13102 {
13103 if (!victim->HealthAbovePct(35))
13104 AddPct(DoneTotalMod, (*i)->GetAmount());
13105 }
13106 // Tundra Stalker
13107 else
13108 {
13109 // Frost Fever (target debuff)
13110 if (victim->HasAura(55095))
13111 AddPct(DoneTotalMod, (*i)->GetAmount());
13112 }
13113 break;
13114 }
13115 // Rage of Rivendare
13116 case 7293:
13117 {
13118 if (victim->GetAuraEffect(SPELL_AURA_PERIODIC_DAMAGE, SPELLFAMILY_DEATHKNIGHT, 0, 0x02000000, 0))
13119 AddPct(DoneTotalMod, (*i)->GetSpellInfo()->GetRank() * 2.0f);
13120 break;
13121 }
13122 // Marked for Death
13123 case 7598:
13124 case 7599:
13125 case 7600:
13126 case 7601:
13127 case 7602:
13128 {
13129 if (victim->GetAuraEffect(SPELL_AURA_MOD_STALKED, SPELLFAMILY_HUNTER, 0x400, 0, 0))
13130 AddPct(DoneTotalMod, (*i)->GetAmount());
13131 break;
13132 }
13133 // Dirty Deeds
13134 case 6427:
13135 case 6428:
13136 {
13137 if (victim->HasAuraState(AURA_STATE_HEALTHLESS_35_PERCENT, spellProto, this))
13138 {
13139 // effect 0 has expected value but in negative state
13140 int32 bonus = -(*i)->GetBase()->GetEffect(0)->GetAmount();
13141 AddPct(DoneTotalMod, bonus);
13142 }
13143 break;
13144 }
13145 }
13146 }
13147
13148 // Custom scripted damage
13149 if (spellProto)
13150 switch (spellProto->SpellFamilyName)
13151 {
13153 // Glacier Rot
13154 if (spellProto->SpellFamilyFlags[0] & 0x2 || spellProto->SpellFamilyFlags[1] & 0x6)
13156 if (victim->GetDiseasesByCaster(owner->GetGUID()) > 0)
13157 AddPct(DoneTotalMod, aurEff->GetAmount());
13158 break;
13159 }
13160
13161 // Some spells don't benefit from done mods
13162 if (spellProto)
13163 if (spellProto->HasAttribute(SPELL_ATTR3_IGNORE_CASTER_MODIFIERS))
13164 {
13165 DoneFlatBenefit = 0;
13166 DoneTotalMod = 1.0f;
13167 }
13168
13169 float tmpDamage = float(int32(pdamage) + DoneFlatBenefit) * DoneTotalMod;
13170
13171 // apply spellmod to Done damage
13172 if (spellProto)
13173 if (Player* modOwner = GetSpellModOwner())
13174 modOwner->ApplySpellMod(spellProto->Id, SPELLMOD_DAMAGE, tmpDamage);
13175
13176 // bonus result can be negative
13177 return uint32(std::max(tmpDamage, 0.0f));
13178}
@ SPELL_EFFECT_NORMALIZED_WEAPON_DMG
Definition: SharedDefines.h:871
@ SPELL_ATTR5_AURA_AFFECTS_NOT_JUST_REQ_EQUIPED_ITEM
Definition: SharedDefines.h:555
@ SPELL_ATTR3_IGNORE_CASTER_MODIFIERS
Definition: SharedDefines.h:494
@ SPELL_AURA_MOD_MELEE_ATTACK_POWER_VERSUS
Definition: SpellAuraDefines.h:165
@ SPELL_AURA_MOD_DAMAGE_DONE_VERSUS
Definition: SpellAuraDefines.h:231
@ SPELL_AURA_MOD_RANGED_ATTACK_POWER_VERSUS
Definition: SpellAuraDefines.h:194
@ SPELL_AURA_MOD_DAMAGE_PERCENT_DONE
Definition: SpellAuraDefines.h:142
@ SPELL_AURA_MOD_DAMAGE_DONE_VERSUS_AURASTATE
Definition: SpellAuraDefines.h:366
@ SPELL_AURA_MOD_DAMAGE_DONE_CREATURE
Definition: SpellAuraDefines.h:122
@ SPELLMOD_DAMAGE
Definition: SpellDefines.h:77
float GetAPMultiplier(WeaponAttackType attType, bool normalized)
Definition: Unit.cpp:17279
AuraEffect * GetDummyAuraEffect(SpellFamilyNames name, uint32 iconId, uint8 effIndex) const
Definition: Unit.h:1973

◆ MeleeDamageBonusTaken()

uint32 Unit::MeleeDamageBonusTaken ( Unit attacker,
uint32  pdamage,
WeaponAttackType  attType,
SpellInfo const *  spellProto = nullptr,
SpellSchoolMask  damageSchoolMask = SPELL_SCHOOL_MASK_NORMAL 
)
13181{
13182 if (pdamage == 0)
13183 return 0;
13184
13185 int32 TakenFlatBenefit = 0;
13186
13187 // ..taken
13189 for (AuraEffectList::const_iterator i = mDamageTaken.begin(); i != mDamageTaken.end(); ++i)
13190 if ((*i)->GetMiscValue() & damageSchoolMask)
13191 TakenFlatBenefit += (*i)->GetAmount();
13192
13193 if (attType != RANGED_ATTACK)
13195 else
13197
13198 // Taken total percent damage auras
13199 float TakenTotalMod = 1.0f;
13200
13202
13203 // .. taken pct (special attacks)
13204 if (spellProto)
13205 {
13206 // From caster spells
13208 for (AuraEffectList::const_iterator i = mOwnerTaken.begin(); i != mOwnerTaken.end(); ++i)
13209 if ((*i)->GetCasterGUID() == attacker->GetGUID() && (*i)->IsAffectedOnSpell(spellProto))
13210 AddPct(TakenTotalMod, (*i)->GetAmount());
13211
13212 // Mod damage from spell mechanic
13213 uint32 mechanicMask = spellProto->GetAllEffectsMechanicMask();
13214
13215 // Shred, Maul - "Effects which increase Bleed damage also increase Shred damage"
13216 if (spellProto->SpellFamilyName == SPELLFAMILY_DRUID && spellProto->SpellFamilyFlags[0] & 0x00008800)
13217 mechanicMask |= (1 << MECHANIC_BLEED);
13218
13219 if (mechanicMask)
13220 {
13222 for (AuraEffectList::const_iterator i = mDamageDoneMechanic.begin(); i != mDamageDoneMechanic.end(); ++i)
13223 if (mechanicMask & uint32(1 << ((*i)->GetMiscValue())))
13224 AddPct(TakenTotalMod, (*i)->GetAmount());
13225 }
13226 }
13227
13228 TakenTotalMod = processDummyAuras(TakenTotalMod);
13229
13230 // .. taken pct: class scripts
13231 /*AuraEffectList const& mclassScritAuras = GetAuraEffectsByType(SPELL_AURA_OVERRIDE_CLASS_SCRIPTS);
13232 for (AuraEffectList::const_iterator i = mclassScritAuras.begin(); i != mclassScritAuras.end(); ++i)
13233 {
13234 switch ((*i)->GetMiscValue())
13235 {
13236 }
13237 }*/
13238
13239 if (attType != RANGED_ATTACK)
13240 {
13242 for (AuraEffectList::const_iterator i = mModMeleeDamageTakenPercent.begin(); i != mModMeleeDamageTakenPercent.end(); ++i)
13243 AddPct(TakenTotalMod, (*i)->GetAmount());
13244 }
13245 else
13246 {
13247 AuraEffectList const& mModRangedDamageTakenPercent = GetAuraEffectsByType(SPELL_AURA_MOD_RANGED_DAMAGE_TAKEN_PCT);
13248 for (AuraEffectList::const_iterator i = mModRangedDamageTakenPercent.begin(); i != mModRangedDamageTakenPercent.end(); ++i)
13249 AddPct(TakenTotalMod, (*i)->GetAmount());
13250 }
13251
13252 // No positive taken bonus, custom attr
13253 if (spellProto)
13254 if (spellProto->HasAttribute(SPELL_ATTR0_CU_NO_POSITIVE_TAKEN_BONUS) && TakenTotalMod > 1.0f)
13255 {
13256 TakenFlatBenefit = 0;
13257 TakenTotalMod = 1.0f;
13258 }
13259
13260 // xinef: sanctified wrath talent
13261 if (TakenTotalMod < 1.0f && attacker->HasAuraType(SPELL_AURA_MOD_IGNORE_TARGET_RESIST))
13262 {
13263 float ignoreModifier = 1.0f - TakenTotalMod;
13264 bool addModifier = false;
13266 for (AuraEffectList::const_iterator j = ResIgnoreAuras.begin(); j != ResIgnoreAuras.end(); ++j)
13267 if ((*j)->GetMiscValue() & damageSchoolMask)
13268 {
13269 ApplyPct(ignoreModifier, (*j)->GetAmount());
13270 addModifier = true;
13271 }
13272
13273 if (addModifier)
13274 TakenTotalMod += ignoreModifier;
13275 }
13276
13277 float tmpDamage = (float(pdamage) + TakenFlatBenefit) * TakenTotalMod;
13278
13279 // bonus result can be negative
13280 return uint32(std::max(tmpDamage, 0.0f));
13281}
@ SPELL_AURA_MOD_RANGED_DAMAGE_TAKEN
Definition: SpellAuraDefines.h:176
@ SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN
Definition: SpellAuraDefines.h:150
@ SPELL_AURA_MOD_MELEE_DAMAGE_TAKEN
Definition: SpellAuraDefines.h:188
@ SPELL_AURA_MOD_MELEE_DAMAGE_TAKEN_PCT
Definition: SpellAuraDefines.h:189
@ SPELL_AURA_MOD_DAMAGE_TAKEN
Definition: SpellAuraDefines.h:77
@ SPELL_AURA_MOD_DAMAGE_FROM_CASTER
Definition: SpellAuraDefines.h:334
@ SPELL_AURA_MOD_MECHANIC_DAMAGE_TAKEN_PERCENT
Definition: SpellAuraDefines.h:318
@ SPELL_AURA_MOD_RANGED_DAMAGE_TAKEN_PCT
Definition: SpellAuraDefines.h:177
@ SPELL_ATTR0_CU_NO_POSITIVE_TAKEN_BONUS
Definition: SpellInfo.h:197
float processDummyAuras(float TakenTotalMod) const
Definition: Unit.cpp:11813

◆ MeleeSpellHitResult()

SpellMissInfo Unit::MeleeSpellHitResult ( Unit victim,
SpellInfo const *  spell 
)
3097{
3098 // Spells with SPELL_ATTR3_ALWAYS_HIT will additionally fully ignore
3099 // resist and deflect chances
3100 if (spellInfo->HasAttribute(SPELL_ATTR3_ALWAYS_HIT))
3101 return SPELL_MISS_NONE;
3102
3103 WeaponAttackType attType = BASE_ATTACK;
3104
3105 // Check damage class instead of attack type to correctly handle judgements
3106 // - they are meele, but can't be dodged/parried/deflected because of ranged dmg class
3107 if (spellInfo->DmgClass == SPELL_DAMAGE_CLASS_RANGED)
3108 attType = RANGED_ATTACK;
3109
3110 int32 attackerWeaponSkill;
3111 // skill value for these spells (for example judgements) is 5* level
3112 if (spellInfo->DmgClass == SPELL_DAMAGE_CLASS_RANGED && !spellInfo->IsRangedWeaponSpell())
3113 attackerWeaponSkill = getLevel() * 5;
3114 // bonus from skills is 0.04% per skill Diff
3115 else
3116 attackerWeaponSkill = int32(GetWeaponSkillValue(attType, victim));
3117
3118 int32 skillDiff = attackerWeaponSkill - int32(victim->GetMaxSkillValueForLevel(this));
3119
3120 uint32 roll = urand (0, 10000);
3121
3122 uint32 missChance = uint32(MeleeSpellMissChance(victim, attType, skillDiff, spellInfo->Id) * 100.0f);
3123 // Roll miss
3124 uint32 tmp = missChance;
3125 if (roll < tmp)
3126 return SPELL_MISS_MISS;
3127
3128 bool canDodge = !spellInfo->HasAttribute(SPELL_ATTR7_NO_ATTACK_DODGE);
3129 bool canParry = !spellInfo->HasAttribute(SPELL_ATTR7_NO_ATTACK_PARRY);
3130 bool canBlock = spellInfo->HasAttribute(SPELL_ATTR3_COMPLETELY_BLOCKED) && !spellInfo->HasAttribute(SPELL_ATTR0_CU_DIRECT_DAMAGE);
3131
3132 // Same spells cannot be parry/dodge
3133 if (spellInfo->HasAttribute(SPELL_ATTR0_NO_ACTIVE_DEFENSE))
3134 return SPELL_MISS_NONE;
3135
3136 // Chance resist mechanic
3137 int32 resist_chance = victim->GetMechanicResistChance(spellInfo) * 100;
3138 tmp += resist_chance;
3139 if (roll < tmp)
3140 return SPELL_MISS_RESIST;
3141
3142 // Ranged attacks can only miss, resist and deflect
3143 if (attType == RANGED_ATTACK)
3144 {
3145 // only if in front
3146 if (!victim->HasUnitState(UNIT_STATE_STUNNED) && (victim->HasInArc(M_PI, this) || victim->HasAuraType(SPELL_AURA_IGNORE_HIT_DIRECTION)))
3147 {
3148 int32 deflect_chance = victim->GetTotalAuraModifier(SPELL_AURA_DEFLECT_SPELLS) * 100;
3149 tmp += deflect_chance;
3150 if (roll < tmp)
3151 return SPELL_MISS_DEFLECT;
3152 }
3153
3154 canDodge = false;
3155 canParry = false;
3156 }
3157
3158 // Check for attack from behind
3159 // xinef: if from behind or spell requires cast from behind
3160 if (!victim->HasInArc(M_PI, this))
3161 {
3163 {
3164 // Can`t dodge from behind in PvP (but its possible in PvE)
3165 if (victim->GetTypeId() == TYPEID_PLAYER)
3166 {
3167 canDodge = false;
3168 }
3169
3170 // Can`t parry or block
3171 canParry = false;
3172 canBlock = false;
3173 }
3174 }
3175
3176 // Check creatures flags_extra for disable parry
3177 if (victim->GetTypeId() == TYPEID_UNIT)
3178 {
3179 uint32 flagEx = victim->ToCreature()->GetCreatureTemplate()->flags_extra;
3180 // Xinef: no dodge flag
3181 if (flagEx & CREATURE_FLAG_EXTRA_NO_DODGE)
3182 canDodge = false;
3183 if (flagEx & CREATURE_FLAG_EXTRA_NO_PARRY)
3184 canParry = false;
3185 // Check creatures flags_extra for disable block
3186 if (flagEx & CREATURE_FLAG_EXTRA_NO_BLOCK)
3187 canBlock = false;
3188 }
3189 // Ignore combat result aura
3191 for (AuraEffectList::const_iterator i = ignore.begin(); i != ignore.end(); ++i)
3192 {
3193 if (!(*i)->IsAffectedOnSpell(spellInfo))
3194 continue;
3195 switch ((*i)->GetMiscValue())
3196 {
3197 case MELEE_HIT_DODGE:
3198 canDodge = false;
3199 break;
3200 case MELEE_HIT_BLOCK:
3201 canBlock = false;
3202 break;
3203 case MELEE_HIT_PARRY:
3204 canParry = false;
3205 break;
3206 default:
3207 LOG_DEBUG("entities.unit", "Spell {} SPELL_AURA_IGNORE_COMBAT_RESULT has unhandled state {}", (*i)->GetId(), (*i)->GetMiscValue());
3208 break;
3209 }
3210 }
3211
3212 if (canDodge)
3213 {
3214 // Roll dodge
3215 int32 dodgeChance = int32(victim->GetUnitDodgeChance() * 100.0f) - skillDiff * 4;
3216 // Reduce enemy dodge chance by SPELL_AURA_MOD_COMBAT_RESULT_CHANCE
3218 dodgeChance = int32(float(dodgeChance) * GetTotalAuraMultiplier(SPELL_AURA_MOD_ENEMY_DODGE));
3219 // Reduce dodge chance by attacker expertise rating
3220 if (GetTypeId() == TYPEID_PLAYER)
3221 dodgeChance -= int32(ToPlayer()->GetExpertiseDodgeOrParryReduction(attType) * 100.0f);
3222 else
3224
3225 // xinef: cant dodge while casting or while stunned
3226 if (dodgeChance < 0 || victim->IsNonMeleeSpellCast(false, false, true) || victim->HasUnitState(UNIT_STATE_CONTROLLED))
3227 dodgeChance = 0;
3228
3229 tmp += dodgeChance;
3230 if (roll < tmp)
3231 return SPELL_MISS_DODGE;
3232 }
3233
3234 if (canParry)
3235 {
3236 // Roll parry
3237 int32 parryChance = int32(victim->GetUnitParryChance() * 100.0f) - skillDiff * 4;
3238 // Reduce parry chance by attacker expertise rating
3239 if (GetTypeId() == TYPEID_PLAYER)
3240 parryChance -= int32(ToPlayer()->GetExpertiseDodgeOrParryReduction(attType) * 100.0f);
3241 else
3243
3244 // xinef: cant parry while casting or while stunned
3245 if (parryChance < 0 || victim->IsNonMeleeSpellCast(false, false, true) || victim->HasUnitState(UNIT_STATE_CONTROLLED))
3246 parryChance = 0;
3247
3248 tmp += parryChance;
3249 if (roll < tmp)
3250 return SPELL_MISS_PARRY;
3251 }
3252
3253 if (canBlock)
3254 {
3255 int32 blockChance = int32(victim->GetUnitBlockChance() * 100.0f) - skillDiff * 4;
3256
3257 // xinef: cant block while casting or while stunned
3258 if (blockChance < 0 || victim->IsNonMeleeSpellCast(false, false, true) || victim->HasUnitState(UNIT_STATE_CONTROLLED))
3259 blockChance = 0;
3260
3261 tmp += blockChance;
3262 if (roll < tmp)
3263 return SPELL_MISS_BLOCK;
3264 }
3265
3266 return SPELL_MISS_NONE;
3267}
@ CREATURE_FLAG_EXTRA_NO_PARRY
Definition: CreatureData.h:51
@ CREATURE_FLAG_EXTRA_NO_DODGE
Definition: CreatureData.h:72
@ SPELL_ATTR7_NO_ATTACK_PARRY
Definition: SharedDefines.h:637
@ SPELL_ATTR7_NO_ATTACK_DODGE
Definition: SharedDefines.h:636
@ SPELL_ATTR3_COMPLETELY_BLOCKED
Definition: SharedDefines.h:468
@ SPELL_MISS_PARRY
Definition: SharedDefines.h:1495
@ SPELL_MISS_DODGE
Definition: SharedDefines.h:1494
@ SPELL_MISS_BLOCK
Definition: SharedDefines.h:1496
@ SPELL_AURA_MOD_EXPERTISE
Definition: SpellAuraDefines.h:303
@ SPELL_AURA_IGNORE_COMBAT_RESULT
Definition: SpellAuraDefines.h:265
@ SPELL_AURA_MOD_ENEMY_DODGE
Definition: SpellAuraDefines.h:314
@ SPELL_AURA_MOD_COMBAT_RESULT_CHANCE
Definition: SpellAuraDefines.h:311
@ SPELL_ATTR0_CU_DIRECT_DAMAGE
Definition: SpellInfo.h:184
@ SPELL_ATTR0_CU_REQ_CASTER_BEHIND_TARGET
Definition: SpellInfo.h:193
float GetUnitDodgeChance() const
Definition: Unit.cpp:3581
float GetTotalAuraMultiplier(AuraType auratype) const
Definition: Unit.cpp:5824
float GetUnitParryChance() const
Definition: Unit.cpp:3598
float MeleeSpellMissChance(Unit const *victim, WeaponAttackType attType, int32 skillDiff, uint32 spellId) const
Definition: Unit.cpp:19020

◆ MeleeSpellMissChance()

float Unit::MeleeSpellMissChance ( Unit const *  victim,
WeaponAttackType  attType,
int32  skillDiff,
uint32  spellId 
) const
19021{
19022 SpellInfo const* spellInfo = spellId ? sSpellMgr->GetSpellInfo(spellId) : nullptr;
19023 if (spellInfo && spellInfo->HasAttribute(SPELL_ATTR7_NO_ATTACK_MISS))
19024 {
19025 return 0.0f;
19026 }
19027
19028 //calculate miss chance
19029 float missChance = victim->GetUnitMissChance(attType);
19030
19031 // Check if dual wielding, add additional miss penalty - when mainhand has on next swing spell, offhand doesnt suffer penalty
19032 if (!spellId && (attType != RANGED_ATTACK) && haveOffhandWeapon() && (!m_currentSpells[CURRENT_MELEE_SPELL] || !m_currentSpells[CURRENT_MELEE_SPELL]->IsNextMeleeSwingSpell()))
19033 {
19034 missChance += 19;
19035 }
19036
19037 // bonus from skills is 0.04%
19038 //miss_chance -= skillDiff * 0.04f;
19039 int32 diff = -skillDiff;
19040 if (victim->GetTypeId() == TYPEID_PLAYER)
19041 missChance += diff > 0 ? diff * 0.04f : diff * 0.02f;
19042 else
19043 missChance += diff > 10 ? 1 + (diff - 10) * 0.4f : diff * 0.1f;
19044
19045 // Calculate hit chance
19046 float hitChance = 100.0f;
19047
19048 // Spellmod from SPELLMOD_RESIST_MISS_CHANCE
19049 if (spellId)
19050 {
19051 if (Player* modOwner = GetSpellModOwner())
19052 modOwner->ApplySpellMod(spellId, SPELLMOD_RESIST_MISS_CHANCE, hitChance);
19053 }
19054
19055 missChance += hitChance - 100.0f;
19056
19057 if (attType == RANGED_ATTACK)
19058 missChance -= m_modRangedHitChance;
19059 else
19060 missChance -= m_modMeleeHitChance;
19061
19062 // Limit miss chance from 0 to 60%
19063 if (missChance < 0.0f)
19064 return 0.0f;
19065 if (missChance > 60.0f)
19066 return 60.0f;
19067 return missChance;
19068}

◆ ModifyAuraState()

void Unit::ModifyAuraState ( AuraStateType  flag,
bool  apply 
)
10446{
10447 if (apply)
10448 {
10449 if (!HasFlag(UNIT_FIELD_AURASTATE, 1 << (flag - 1)))
10450 {
10451 SetFlag(UNIT_FIELD_AURASTATE, 1 << (flag - 1));
10452 Unit::AuraMap& tAuras = GetOwnedAuras();
10453 for (Unit::AuraMap::iterator itr = tAuras.begin(); itr != tAuras.end(); ++itr)
10454 {
10455 if( (*itr).second->IsRemoved() )
10456 continue;
10457
10458 if( (*itr).second->GetSpellInfo()->CasterAuraState == flag )
10459 if( AuraApplication* aurApp = (*itr).second->GetApplicationOfTarget(GetGUID()) )
10460 (*itr).second->HandleAllEffects(aurApp, AURA_EFFECT_HANDLE_REAL, true);
10461 }
10462 }
10463 }
10464 else
10465 {
10466 if (HasFlag(UNIT_FIELD_AURASTATE, 1 << (flag - 1)))
10467 {
10468 RemoveFlag(UNIT_FIELD_AURASTATE, 1 << (flag - 1));
10469
10470 if (flag != AURA_STATE_ENRAGE) // enrage aura state triggering continues auras
10471 {
10472 Unit::AuraMap& tAuras = GetOwnedAuras();
10473 for (Unit::AuraMap::iterator itr = tAuras.begin(); itr != tAuras.end(); ++itr)
10474 {
10475 if( (*itr).second->GetSpellInfo()->CasterAuraState == flag )
10476 if( AuraApplication* aurApp = (*itr).second->GetApplicationOfTarget(GetGUID()) )
10477 (*itr).second->HandleAllEffects(aurApp, AURA_EFFECT_HANDLE_REAL, false);
10478 }
10479 }
10480 }
10481 }
10482}
@ AURA_STATE_ENRAGE
Definition: SharedDefines.h:1281
@ AURA_EFFECT_HANDLE_REAL
Definition: SpellAuraDefines.h:42
void SetFlag(uint16 index, uint32 newFlag)
Definition: Object.cpp:845
void RemoveFlag(uint16 index, uint32 oldFlag)
Definition: Object.cpp:860
std::multimap< uint32, Aura * > AuraMap
Definition: Unit.h:1295
AuraMap & GetOwnedAuras()
Definition: Unit.h:1911

◆ ModifyHealth()

int32 Unit::ModifyHealth ( int32  val)
13982{
13983 int32 gain = 0;
13984
13985 if (dVal == 0)
13986 return 0;
13987
13988 int32 curHealth = (int32)GetHealth();
13989
13990 int32 val = dVal + curHealth;
13991 if (val <= 0)
13992 {
13993 SetHealth(0);
13994 return -curHealth;
13995 }
13996
13997 int32 maxHealth = (int32)GetMaxHealth();
13998
13999 if (val < maxHealth)
14000 {
14001 SetHealth(val);
14002 gain = val - curHealth;
14003 }
14004 else if (curHealth != maxHealth)
14005 {
14006 SetHealth(maxHealth);
14007 gain = maxHealth - curHealth;
14008 }
14009
14010 return gain;
14011}

◆ ModifyPower()

int32 Unit::ModifyPower ( Powers  power,
int32  val,
bool  withPowerUpdate = true 
)
14040{
14041 if (dVal == 0)
14042 return 0;
14043
14044 int32 gain = 0;
14045
14046 int32 curPower = (int32)GetPower(power);
14047
14048 int32 val = dVal + curPower;
14049 if (val <= 0)
14050 {
14051 SetPower(power, 0, withPowerUpdate);
14052 return -curPower;
14053 }
14054
14055 int32 maxPower = (int32)GetMaxPower(power);
14056
14057 if (val < maxPower)
14058 {
14059 SetPower(power, val, withPowerUpdate);
14060 gain = val - curPower;
14061 }
14062 else if (curPower != maxPower)
14063 {
14064 SetPower(power, maxPower, withPowerUpdate);
14065 gain = maxPower - curPower;
14066 }
14067
14068 return gain;
14069}
void SetPower(Powers power, uint32 val, bool withPowerUpdate=true)
Definition: Unit.cpp:15423

◆ ModifyPowerPct()

int32 Unit::ModifyPowerPct ( Powers  power,
float  pct,
bool  apply = true 
)
14073{
14074 float amount = (float)GetMaxPower(power);
14075 ApplyPercentModFloatVar(amount, pct, apply);
14076
14077 return ModifyPower(power, (int32)amount - (int32)GetMaxPower(power));
14078}

◆ ModifyRedirectThreat()

void Unit::ModifyRedirectThreat ( int32  amount)
inline
void ModifyThreatPct(int32 amount)
Definition: Unit.h:962

◆ ModSpellCastTime()

void Unit::ModSpellCastTime ( SpellInfo const *  spellProto,
int32 castTime,
Spell spell = nullptr 
)
14831{
14832 if (!spellInfo || castTime < 0)
14833 return;
14834
14835 if (spellInfo->IsChanneled() && spellInfo->HasAura(SPELL_AURA_MOUNTED))
14836 return;
14837
14838 // called from caster
14839 if (Player* modOwner = GetSpellModOwner())
14840 // TODO:(MadAgos) Eventually check and delete the bool argument
14841 modOwner->ApplySpellMod(spellInfo->Id, SPELLMOD_CASTING_TIME, castTime, spell, bool(modOwner != this && !IsPet()));
14842
14843 switch (spellInfo->DmgClass)
14844 {
14846 if (spellInfo->AttributesEx5 & SPELL_ATTR5_SPELL_HASTE_AFFECTS_PERIODIC) // required double check
14847 castTime = int32(float(castTime) * GetFloatValue(UNIT_MOD_CAST_SPEED));
14848 else if (spellInfo->SpellVisual[0] == 3881 && HasAura(67556)) // cooking with Chef Hat.
14849 castTime = 500;
14850 break;
14852 break; // no known cases
14854 castTime = CanInstantCast() ? 0 : int32(float(castTime) * GetFloatValue(UNIT_MOD_CAST_SPEED));
14855 break;
14857 castTime = int32(float(castTime) * m_modAttackSpeedPct[RANGED_ATTACK]);
14858 break;
14859 default:
14860 break;
14861 }
14862}
@ SPELL_ATTR5_SPELL_HASTE_AFFECTS_PERIODIC
Definition: SharedDefines.h:552
@ SPELLMOD_CASTING_TIME
Definition: SpellDefines.h:87
bool CanInstantCast() const
Definition: Unit.h:2432

◆ ModSpellDuration()

int32 Unit::ModSpellDuration ( SpellInfo const *  spellProto,
Unit const *  target,
int32  duration,
bool  positive,
uint32  effectMask 
)
14731{
14732 // don't mod permanent auras duration
14733 if (duration < 0)
14734 return duration;
14735
14736 // some auras are not affected by duration modifiers
14737 if (spellProto->HasAttribute(SPELL_ATTR7_NO_TARGET_DURATION_MOD))
14738 return duration;
14739
14740 // cut duration only of negative effects
14741 // xinef: also calculate self casts, spell can be reflected for example
14742 if (!positive)
14743 {
14744 int32 mechanic = spellProto->GetSpellMechanicMaskByEffectMask(effectMask);
14745
14746 int32 durationMod;
14747 int32 durationMod_always = 0;
14748 int32 durationMod_not_stack = 0;
14749
14750 for (uint8 i = 1; i <= MECHANIC_ENRAGED; ++i)
14751 {
14752 if (!(mechanic & 1 << i))
14753 continue;
14754
14755 // Xinef: spells affecting movement imparing effects should not reduce duration if disoriented mechanic is present
14756 if (i == MECHANIC_SNARE && (mechanic & (1 << MECHANIC_DISORIENTED)))
14757 continue;
14758
14759 // Find total mod value (negative bonus)
14760 int32 new_durationMod_always = target->GetTotalAuraModifierByMiscValue(SPELL_AURA_MECHANIC_DURATION_MOD, i);
14761 // Find max mod (negative bonus)
14762 int32 new_durationMod_not_stack = target->GetMaxNegativeAuraModifierByMiscValue(SPELL_AURA_MECHANIC_DURATION_MOD_NOT_STACK, i);
14763 // Check if mods applied before were weaker
14764 if (new_durationMod_always < durationMod_always)
14765 durationMod_always = new_durationMod_always;
14766 if (new_durationMod_not_stack < durationMod_not_stack)
14767 durationMod_not_stack = new_durationMod_not_stack;
14768 }
14769
14770 // Select strongest negative mod
14771 if (durationMod_always > durationMod_not_stack)
14772 durationMod = durationMod_not_stack;
14773 else
14774 durationMod = durationMod_always;
14775
14776 if (durationMod != 0)
14777 AddPct(duration, durationMod);
14778
14779 // there are only negative mods currently
14780 durationMod_always = target->GetTotalAuraModifierByMiscValue(SPELL_AURA_MOD_AURA_DURATION_BY_DISPEL, spellProto->Dispel);
14781 durationMod_not_stack = target->GetMaxNegativeAuraModifierByMiscValue(SPELL_AURA_MOD_AURA_DURATION_BY_DISPEL_NOT_STACK, spellProto->Dispel);
14782
14783 durationMod = 0;
14784 if (durationMod_always > durationMod_not_stack)
14785 durationMod += durationMod_not_stack;
14786 else
14787 durationMod += durationMod_always;
14788
14789 if (durationMod != 0)
14790 AddPct(duration, durationMod);
14791 }
14792 else
14793 {
14794 // else positive mods here, there are no currently
14795 // when there will be, change GetTotalAuraModifierByMiscValue to GetTotalPositiveAuraModifierByMiscValue
14796 }
14797
14798 // Glyphs which increase duration of selfcasted buffs
14799 if (target == this)
14800 {
14801 switch (spellProto->SpellFamilyName)
14802 {
14803 case SPELLFAMILY_DRUID:
14804 if (spellProto->SpellFamilyFlags[0] & 0x100)
14805 {
14806 // Glyph of Thorns
14807 if (AuraEffect* aurEff = GetAuraEffect(57862, 0))
14808 duration += aurEff->GetAmount() * MINUTE * IN_MILLISECONDS;
14809 }
14810 break;
14812 if ((spellProto->SpellFamilyFlags[0] & 0x00000002) && spellProto->SpellIconID == 298)
14813 {
14814 // Glyph of Blessing of Might
14815 if (AuraEffect* aurEff = GetAuraEffect(57958, 0))
14816 duration += aurEff->GetAmount() * MINUTE * IN_MILLISECONDS;
14817 }
14818 else if ((spellProto->SpellFamilyFlags[0] & 0x00010000) && spellProto->SpellIconID == 306)
14819 {
14820 // Glyph of Blessing of Wisdom
14821 if (AuraEffect* aurEff = GetAuraEffect(57979, 0))
14822 duration += aurEff->GetAmount() * MINUTE * IN_MILLISECONDS;
14823 }
14824 break;
14825 }
14826 }
14827 return std::max(duration, 0);
14828}
constexpr auto MINUTE
Definition: Common.h:56
@ SPELL_ATTR7_NO_TARGET_DURATION_MOD
Definition: SharedDefines.h:614
@ MECHANIC_ENRAGED
Definition: SharedDefines.h:1328
@ MECHANIC_DISORIENTED
Definition: SharedDefines.h:1299
@ SPELL_AURA_MOD_AURA_DURATION_BY_DISPEL_NOT_STACK
Definition: SpellAuraDefines.h:309
@ SPELL_AURA_MECHANIC_DURATION_MOD_NOT_STACK
Definition: SpellAuraDefines.h:297
@ SPELL_AURA_MOD_AURA_DURATION_BY_DISPEL
Definition: SpellAuraDefines.h:308
@ SPELL_AURA_MECHANIC_DURATION_MOD
Definition: SpellAuraDefines.h:295

◆ MonsterMoveWithSpeed()

void Unit::MonsterMoveWithSpeed ( float  x,
float  y,
float  z,
float  speed 
)
548{
549 Movement::MoveSplineInit init(this);
550 init.MoveTo(x, y, z);
551 init.SetVelocity(speed);
552 init.Launch();
553}

◆ Mount()

void Unit::Mount ( uint32  mount,
uint32  vehicleId = 0,
uint32  creatureEntry = 0 
)
13370{
13371 if (mount)
13373
13375
13376 if (Player* player = ToPlayer())
13377 {
13378 sScriptMgr->AnticheatSetUnderACKmount(player);
13379
13380 // mount as a vehicle
13381 if (VehicleId)
13382 {
13383 if (CreateVehicleKit(VehicleId, creatureEntry))
13384 {
13385 GetVehicleKit()->Reset();
13386
13387 // Send others that we now have a vehicle
13389 data << GetPackGUID();
13390 data << uint32(VehicleId);
13391 SendMessageToSet(&data, true);
13392
13394 player->GetSession()->SendPacket(&data);
13395
13396 // mounts can also have accessories
13398 }
13399 }
13400
13401 // unsummon pet
13402 Pet* pet = player->GetPet();
13403 if (pet)
13404 {
13406 // don't unsummon pet in arena but SetFlag UNIT_FLAG_STUNNED to disable pet's interface
13407 if (bg && bg->isArena())
13409 else
13410 player->UnsummonPetTemporaryIfAny();
13411 }
13412
13413 // xinef: if we have charmed npc, stun him also
13414 if (Unit* charm = player->GetCharm())
13415 if (charm->GetTypeId() == TYPEID_UNIT)
13416 charm->SetUnitFlag(UNIT_FLAG_STUNNED);
13417
13418 WorldPacket data(SMSG_MOVE_SET_COLLISION_HGT, GetPackGUID().size() + 4 + 4);
13419 data << GetPackGUID();
13420 data << uint32(GameTime::GetGameTime().count()); // Packet counter
13421 data << player->GetCollisionHeight();
13422 player->GetSession()->SendPacket(&data);
13423 }
13424
13426}
@ AURA_INTERRUPT_FLAG_MOUNT
Definition: SpellDefines.h:61
bool isArena() const
Definition: Battleground.h:388
bool CreateVehicleKit(uint32 id, uint32 creatureEntry)
Definition: Unit.cpp:18747
void Reset(bool evading=false)
Definition: Vehicle.cpp:118
void InstallAllAccessories(bool evading)
Definition: Vehicle.cpp:85

◆ NearTeleportTo() [1/2]

void Unit::NearTeleportTo ( float  x,
float  y,
float  z,
float  orientation,
bool  casting = false,
bool  vehicleTeleport = false,
bool  withPet = false,
bool  removeTransport = false 
)
19994{
19995 DisableSpline();
19996 if (GetTypeId() == TYPEID_PLAYER)
19997 ToPlayer()->TeleportTo(GetMapId(), x, y, z, orientation, TELE_TO_NOT_LEAVE_COMBAT | (removeTransport ? 0 : TELE_TO_NOT_LEAVE_TRANSPORT) | TELE_TO_NOT_UNSUMMON_PET | (casting ? TELE_TO_SPELL : 0) | (vehicleTeleport ? TELE_TO_NOT_LEAVE_VEHICLE : 0) | (withPet ? TELE_TO_WITH_PET : 0));
19998 else
19999 {
20000 Position pos = {x, y, z, orientation};
20001 SendTeleportPacket(pos);
20002 UpdatePosition(x, y, z, orientation, true);
20005 }
20006}
@ TELE_TO_WITH_PET
Definition: Player.h:820
@ TELE_TO_NOT_LEAVE_VEHICLE
Definition: Player.h:819
@ TELE_TO_SPELL
Definition: Player.h:818
@ TELE_TO_NOT_LEAVE_COMBAT
Definition: Player.h:816
@ TELE_TO_NOT_UNSUMMON_PET
Definition: Player.h:817
@ TELE_TO_NOT_LEAVE_TRANSPORT
Definition: Player.h:815
void ReinitializeMovement()
Definition: MotionMaster.cpp:808
bool TeleportTo(uint32 mapid, float x, float y, float z, float orientation, uint32 options=0, Unit *target=nullptr, bool newInstance=false)
Definition: Player.cpp:1311
void SendTeleportPacket(Position &pos)
Definition: Unit.cpp:20015
void UpdateObjectVisibility(bool forced=true, bool fromUpdate=false) override
Definition: Unit.cpp:19162
virtual bool UpdatePosition(float x, float y, float z, float ang, bool teleport=false)
Definition: Unit.cpp:20031

◆ NearTeleportTo() [2/2]

void Unit::NearTeleportTo ( Position pos,
bool  casting = false,
bool  vehicleTeleport = false,
bool  withPet = false,
bool  removeTransport = false 
)
19989{
19990 NearTeleportTo(pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), pos.GetOrientation(), casting, vehicleTeleport, withPet, removeTransport);
19991}
void NearTeleportTo(Position &pos, bool casting=false, bool vehicleTeleport=false, bool withPet=false, bool removeTransport=false)
Definition: Unit.cpp:19988

◆ OutDebugInfo()

void Unit::OutDebugInfo ( ) const
20239{
20240 LOG_ERROR("entities.unit", "Unit::OutDebugInfo");
20241 LOG_INFO("entities.unit", "GUID {}, name {}", GetGUID().ToString(), GetName());
20242 LOG_INFO("entities.unit", "OwnerGUID {}, MinionGUID {}, CharmerGUID {}, CharmedGUID {}",
20244 LOG_INFO("entities.unit", "In world {}, unit type mask {}", (uint32)(IsInWorld() ? 1 : 0), m_unitTypeMask);
20245 if (IsInWorld())
20246 LOG_INFO("entities.unit", "Mapid {}", GetMapId());
20247
20248 LOG_INFO("entities.unit", "Summon Slot: ");
20249 for (uint32 i = 0; i < MAX_SUMMON_SLOT; ++i)
20250 LOG_INFO("entities.unit", "{}, ", m_SummonSlot[i].ToString());
20251 LOG_INFO("server.loading", " ");
20252
20253 LOG_INFO("entities.unit", "Controlled List: ");
20254 for (ControlSet::const_iterator itr = m_Controlled.begin(); itr != m_Controlled.end(); ++itr)
20255 LOG_INFO("entities.unit", "{}, ", (*itr)->GetGUID().ToString());
20256 LOG_INFO("server.loading", " ");
20257
20258 LOG_INFO("entities.unit", "Aura List: ");
20259 for (AuraApplicationMap::const_iterator itr = m_appliedAuras.begin(); itr != m_appliedAuras.end(); ++itr)
20260 LOG_INFO("entities.unit", "{}, ", itr->first);
20261 LOG_INFO("server.loading", " ");
20262
20263 if (IsVehicle())
20264 {
20265 LOG_INFO("entities.unit", "Passenger List: ");
20266 for (SeatMap::iterator itr = GetVehicleKit()->Seats.begin(); itr != GetVehicleKit()->Seats.end(); ++itr)
20267 if (Unit* passenger = ObjectAccessor::GetUnit(*GetVehicleBase(), itr->second.Passenger.Guid))
20268 LOG_INFO("entities.unit", "{}, ", passenger->GetGUID().ToString());
20269 LOG_INFO("server.loading", " ");
20270 }
20271
20272 if (GetVehicle())
20273 LOG_INFO("entities.unit", "On vehicle {}.", GetVehicleBase()->GetEntry());
20274}
Seats
Definition: boss_flame_leviathan.cpp:159

◆ PauseMovement()

void Unit::PauseMovement ( uint32  timer = 0,
uint8  slot = 0 
)
virtual
16756{
16757 if (slot >= MAX_MOTION_SLOT)
16758 return;
16759
16760 if (MovementGenerator* movementGenerator = GetMotionMaster()->GetMotionSlot(slot))
16761 movementGenerator->Pause(timer);
16762
16763 StopMoving();
16764}
@ MAX_MOTION_SLOT
Definition: MotionMaster.h:64
Definition: MovementGenerator.h:30
void StopMoving()
Definition: Unit.cpp:16736

◆ PetSpellFail()

void Unit::PetSpellFail ( SpellInfo const *  spellInfo,
Unit target,
uint32  result 
)
20427{
20428 CharmInfo* charmInfo = GetCharmInfo();
20429 if (!charmInfo || GetTypeId() != TYPEID_UNIT)
20430 return;
20431
20433 {
20434 if ((result == SPELL_FAILED_LINE_OF_SIGHT || result == SPELL_FAILED_OUT_OF_RANGE) || !ToCreature()->HasReactState(REACT_PASSIVE))
20435 if (Unit* owner = GetOwner())
20436 {
20437 if (spellInfo->IsPositive() && IsFriendlyTo(target))
20438 {
20439 AttackStop();
20440 charmInfo->SetIsAtStay(false);
20441 charmInfo->SetIsCommandAttack(true);
20442 charmInfo->SetIsReturning(false);
20443 charmInfo->SetIsFollowing(false);
20444
20445 GetMotionMaster()->MoveFollow(target, PET_FOLLOW_DIST, rand_norm() * 2 * M_PI);
20446 }
20447 else if (owner->IsValidAttackTarget(target))
20448 {
20449 AttackStop();
20450 charmInfo->SetIsAtStay(false);
20451 charmInfo->SetIsCommandAttack(true);
20452 charmInfo->SetIsReturning(false);
20453 charmInfo->SetIsFollowing(false);
20454
20455 if (!ToCreature()->HasReactState(REACT_PASSIVE))
20456 ToCreature()->AI()->AttackStart(target);
20457 else
20458 GetMotionMaster()->MoveChase(target);
20459 }
20460 }
20461
20462 // can be extended in future
20463 if (result == SPELL_FAILED_LINE_OF_SIGHT || result == SPELL_FAILED_OUT_OF_RANGE)
20464 {
20465 charmInfo->SetForcedSpell(spellInfo->IsPositive() ? -int32(spellInfo->Id) : spellInfo->Id);
20466 charmInfo->SetForcedTargetGUID(target->GetGUID());
20467 }
20468 else
20469 {
20470 charmInfo->SetForcedSpell(0);
20472 }
20473 }
20474}
#define PET_FOLLOW_DIST
Definition: PetDefines.h:193
@ SPELL_FAILED_OUT_OF_RANGE
Definition: SharedDefines.h:1018
@ SPELL_FAILED_LINE_OF_SIGHT
Definition: SharedDefines.h:968
void MoveChase(Unit *target, std::optional< ChaseRange > dist={}, std::optional< ChaseAngle > angle={})
Definition: MotionMaster.cpp:299
void MoveFollow(Unit *target, float dist, float angle, MovementSlot slot=MOTION_SLOT_ACTIVE)
Definition: MotionMaster.cpp:367
virtual void AttackStart(Unit *)
Definition: UnitAI.cpp:28
bool IsPathfindingEnabled(const Map *map)
Definition: DisableMgr.cpp:402
void SetIsAtStay(bool val)
Definition: Unit.cpp:20396
void SetIsFollowing(bool val)
Definition: Unit.cpp:20406
void SetIsReturning(bool val)
Definition: Unit.cpp:20416
void SetForcedSpell(uint32 id)
Definition: Unit.h:1144
void SetForcedTargetGUID(ObjectGuid guid=ObjectGuid::Empty)
Definition: Unit.h:1146
void SetIsCommandAttack(bool val)
Definition: Unit.cpp:20334

◆ ProcDamageAndSpell()

void Unit::ProcDamageAndSpell ( Unit actor,
Unit victim,
uint32  procAttacker,
uint32  procVictim,
uint32  procEx,
uint32  amount,
WeaponAttackType  attType = BASE_ATTACK,
SpellInfo const *  procSpellInfo = nullptr,
SpellInfo const *  procAura = nullptr,
int8  procAuraEffectIndex = -1,
Spell const *  procSpell = nullptr,
DamageInfo damageInfo = nullptr,
HealInfo healInfo = nullptr,
uint32  procPhase = 2 
)
static
6279{
6280 // Not much to do if no flags are set.
6281 if (procAttacker && actor)
6282 actor->ProcDamageAndSpellFor(false, victim, procAttacker, procExtra, attType, procSpellInfo, amount, procAura, procAuraEffectIndex, procSpell, damageInfo, healInfo, procPhase);
6283 // Now go on with a victim's events'n'auras
6284 // Not much to do if no flags are set or there is no victim
6285 if (victim && victim->IsAlive() && procVictim)
6286 victim->ProcDamageAndSpellFor(true, actor, procVictim, procExtra, attType, procSpellInfo, amount, procAura, procAuraEffectIndex, procSpell, damageInfo, healInfo, procPhase);
6287}

◆ ProcDamageAndSpellFor()

void Unit::ProcDamageAndSpellFor ( bool  isVictim,
Unit target,
uint32  procFlag,
uint32  procExtra,
WeaponAttackType  attType,
SpellInfo const *  procSpellInfo,
uint32  damage,
SpellInfo const *  procAura = nullptr,
int8  procAuraEffectIndex = -1,
Spell const *  procSpell = nullptr,
DamageInfo damageInfo = nullptr,
HealInfo healInfo = nullptr,
uint32  procPhase = 2 
)
16153{
16154 // Player is loaded now - do not allow passive spell casts to proc
16155 if (GetTypeId() == TYPEID_PLAYER && ToPlayer()->GetSession()->PlayerLoading())
16156 return;
16157 // For melee/ranged based attack need update skills and set some Aura states if victim present
16158 if (procFlag & MELEE_BASED_TRIGGER_MASK && target && procPhase == PROC_SPELL_PHASE_HIT)
16159 {
16160 // Xinef: Shaman in ghost wolf form cant proc anything melee based
16161 if (!isVictim && GetShapeshiftForm() == FORM_GHOSTWOLF)
16162 return;
16163
16164 // Update skills here for players
16165 // only when you are not fighting other players or their pets/totems (pvp)
16166 if (IsPlayer() && !target->IsCharmedOwnedByPlayerOrPlayer())
16167 {
16168 // On melee based hit/miss/resist/parry/dodge need to update skill (for victim and attacker)
16170 {
16171 ToPlayer()->UpdateCombatSkills(target, attType, isVictim, procSpell ? procSpell->m_weaponItem : nullptr);
16172 }
16173 // Update defence if player is victim and we block - TODO: confirm that blocked attacks only have a chance to increase defence skill
16174 else if (isVictim && procExtra & (PROC_EX_BLOCK))
16175 {
16176 ToPlayer()->UpdateCombatSkills(target, attType, true);
16177 }
16178 }
16179 // If exist crit/parry/dodge/block need update aura state (for victim and attacker)
16181 {
16182 // for victim
16183 if (isVictim)
16184 {
16185 // if victim and dodge attack
16186 if (procExtra & PROC_EX_DODGE)
16187 {
16188 // Update AURA_STATE on dodge
16189 if (getClass() != CLASS_ROGUE) // skip Rogue Riposte
16190 {
16193 }
16194 }
16195 // if victim and parry attack
16196 if (procExtra & PROC_EX_PARRY)
16197 {
16198 // For Hunters only Counterattack (skip Mongoose bite)
16199 if (getClass() == CLASS_HUNTER)
16200 {
16203 }
16204 else
16205 {
16208 }
16209 }
16210 // if and victim block attack
16211 if (procExtra & PROC_EX_BLOCK)
16212 {
16215 }
16216 }
16217 else // For attacker
16218 {
16219 // Overpower on victim dodge
16220 if (procExtra & PROC_EX_DODGE)
16221 {
16222 if (getClass() == CLASS_WARRIOR)
16223 {
16224 AddComboPoints(target, 1);
16226 }
16227 }
16228
16229 // Wolverine Bite
16230 if ((procExtra & PROC_HIT_CRITICAL) && IsHunterPet())
16231 {
16232 AddComboPoints(target, 1);
16234 }
16235 }
16236 }
16237 }
16238
16239 Unit* actor = isVictim ? target : this;
16240 Unit* actionTarget = !isVictim ? target : this;
16241
16242 ProcEventInfo eventInfo = ProcEventInfo(actor, actionTarget, target, procFlag, 0, procPhase, procExtra, procSpell, damageInfo, healInfo, procAura, procAuraEffectIndex);
16243
16244 ProcTriggeredList procTriggered;
16245 // Fill procTriggered list
16246 for (AuraApplicationMap::const_iterator itr = GetAppliedAuras().begin(); itr != GetAppliedAuras().end(); ++itr)
16247 {
16248 // Do not allow auras to proc from effect triggered by itself
16249 if (procAura && procAura->Id == itr->first)
16250 continue;
16251
16252 // Xinef: Generic Item Equipment cooldown, -1 is a special marker
16253 if (itr->second->GetBase()->GetCastItemGUID() && HasSpellItemCooldown(itr->first, uint32(-1)))
16254 continue;
16255
16256 ProcTriggeredData triggerData(itr->second->GetBase());
16257 // Defensive procs are active on absorbs (so absorption effects are not a hindrance)
16258 bool active = damage || (procExtra & PROC_EX_BLOCK && isVictim);
16259 if (isVictim)
16260 procExtra &= ~PROC_EX_INTERNAL_REQ_FAMILY;
16261
16262 SpellInfo const* spellProto = itr->second->GetBase()->GetSpellInfo();
16263
16264 // only auras that have trigger spell should proc from fully absorbed damage
16265 if (procExtra & PROC_EX_ABSORB && isVictim)
16266 if (damage || spellProto->Effects[EFFECT_0].TriggerSpell || spellProto->Effects[EFFECT_1].TriggerSpell || spellProto->Effects[EFFECT_2].TriggerSpell)
16267 active = true;
16268
16269 // xinef: fix spell procing from damaging / healing casts if spell has DoT / HoT effect only
16270 // only player spells are taken into account
16271 if (!active && !isVictim && !(procFlag & PROC_FLAG_DONE_PERIODIC) && procSpellInfo && procSpellInfo->SpellFamilyName && (procSpellInfo->HasAura(SPELL_AURA_PERIODIC_DAMAGE) || procSpellInfo->HasAura(SPELL_AURA_PERIODIC_HEAL)))
16272 active = true;
16273
16274 // AuraScript Hook
16275 if (!triggerData.aura->CallScriptCheckProcHandlers(itr->second, eventInfo))
16276 {
16277 continue;
16278 }
16279
16280 bool isTriggeredAtSpellProcEvent = IsTriggeredAtSpellProcEvent(target, triggerData.aura, attType, isVictim, active, triggerData.spellProcEvent, eventInfo);
16281
16282 // AuraScript Hook
16283 triggerData.aura->CallScriptCheckAfterProcHandlers(itr->second, eventInfo);
16284
16285 if (!isTriggeredAtSpellProcEvent)
16286 {
16287 continue;
16288 }
16289
16290 // do checks using conditions table
16291 ConditionList conditions = sConditionMgr->GetConditionsForNotGroupedEntry(CONDITION_SOURCE_TYPE_SPELL_PROC, spellProto->Id);
16292 ConditionSourceInfo condInfo = ConditionSourceInfo(eventInfo.GetActor(), eventInfo.GetActionTarget());
16293 if (!sConditionMgr->IsObjectMeetToConditions(condInfo, conditions))
16294 {
16295 continue;
16296 }
16297
16298 // Triggered spells not triggering additional spells
16299 //bool triggered = !spellProto->HasAttribute(SPELL_ATTR3_CAN_PROC_FROM_PROCS) ?
16300 // (procExtra & PROC_EX_INTERNAL_TRIGGERED && !(procFlag & PROC_FLAG_DONE_TRAP_ACTIVATION)) : false;
16301
16302 bool hasTriggeredProc = false;
16303 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
16304 {
16305 if (itr->second->HasEffect(i))
16306 {
16307 AuraEffect* aurEff = itr->second->GetBase()->GetEffect(i);
16308
16309 // Skip this auras
16310 if (isNonTriggerAura[aurEff->GetAuraType()])
16311 continue;
16312
16313 // If not trigger by default and spellProcEvent == nullptr - skip
16314 if (!isTriggerAura[aurEff->GetAuraType()] && !triggerData.spellProcEvent)
16315 continue;
16316
16317 switch (aurEff->GetAuraType())
16318 {
16321 case SPELL_AURA_DUMMY:
16323 if (uint32 triggerSpellId = aurEff->GetSpellInfo()->Effects[i].TriggerSpell)
16324 {
16325 triggerData.triggerSpelId[i] = triggerSpellId;
16326 hasTriggeredProc = true;
16327 }
16328 break;
16329 default:
16330 break;
16331 }
16332
16333 // Some spells must always trigger
16334 //if (isAlwaysTriggeredAura[aurEff->GetAuraType()])
16335 triggerData.effMask |= 1 << i;
16336 }
16337 }
16338
16339 if (triggerData.effMask)
16340 {
16341 // If there is aura that triggers another proc aura, make sure that the triggered one is going to be proccessed on top of it
16342 if (hasTriggeredProc)
16343 {
16344 bool proccessed = false;
16345 for (uint8 i = 0; i < EFFECT_ALL; ++i)
16346 {
16347 if (uint32 triggeredSpellId = triggerData.triggerSpelId[i])
16348 {
16349 auto iter = std::find(procTriggered.begin(), procTriggered.end(), triggeredSpellId);
16350 if (iter != procTriggered.end())
16351 {
16352 std::advance(iter, 1);
16353 procTriggered.insert(iter, triggerData);
16354 proccessed = true;
16355 break;
16356 }
16357 }
16358 }
16359
16360 if (!proccessed)
16361 {
16362 procTriggered.push_front(triggerData);
16363 }
16364 }
16365 else
16366 {
16367 procTriggered.push_front(triggerData);
16368 }
16369 }
16370 }
16371
16372 // Nothing found
16373 if (procTriggered.empty())
16374 return;
16375
16376 // Note: must SetCantProc(false) before return
16378 SetCantProc(true);
16379
16380 // Handle effects proceed this time
16381 for (ProcTriggeredList::const_iterator i = procTriggered.begin(); i != procTriggered.end(); ++i)
16382 {
16383 // look for aura in auras list, it may be removed while proc event processing
16384 if (i->aura->IsRemoved())
16385 continue;
16386
16387 bool useCharges = i->aura->IsUsingCharges();
16388 // no more charges to use, prevent proc
16389 if (useCharges && !i->aura->GetCharges())
16390 continue;
16391
16392 bool takeCharges = false;
16393 SpellInfo const* spellInfo = i->aura->GetSpellInfo();
16394
16395 AuraApplication* aurApp = i->aura->GetApplicationOfTarget(GetGUID());
16396
16397 bool prepare = i->aura->CallScriptPrepareProcHandlers(aurApp, eventInfo);
16398
16399 // For players set spell cooldown if need
16400 uint32 cooldown = 0;
16401 if (prepare && i->spellProcEvent && i->spellProcEvent->cooldown)
16402 cooldown = i->spellProcEvent->cooldown;
16403
16404 // Xinef: set cooldown for actual proc
16405 eventInfo.SetProcCooldown(cooldown);
16406
16407 // Note: must SetCantProc(false) before return
16409 SetCantProc(true);
16410
16411 bool handled = i->aura->CallScriptProcHandlers(aurApp, eventInfo);
16412
16413 // "handled" is needed as long as proc can be handled in multiple places
16414 if (!handled && HandleAuraProc(target, damage, i->aura, procSpellInfo, procFlag, procExtra, cooldown, &handled))
16415 {
16416 uint32 Id = i->aura->GetId();
16417 LOG_DEBUG("spells.aura", "ProcDamageAndSpell: casting spell {} (triggered with value by {} aura of spell {})", spellInfo->Id, (isVictim ? "a victim's" : "an attacker's"), Id);
16418 takeCharges = true;
16419 }
16420
16421 if (!handled)
16422 for (uint8 effIndex = 0; effIndex < MAX_SPELL_EFFECTS; ++effIndex)
16423 {
16424 if (!(i->effMask & (1 << effIndex)))
16425 continue;
16426
16427 AuraEffect* triggeredByAura = i->aura->GetEffect(effIndex);
16428 ASSERT(triggeredByAura);
16429
16430 bool prevented = i->aura->CallScriptEffectProcHandlers(triggeredByAura, aurApp, eventInfo);
16431 if (prevented)
16432 {
16433 takeCharges = true;
16434 continue;
16435 }
16436
16437 switch (triggeredByAura->GetAuraType())
16438 {
16440 {
16441 LOG_DEBUG("spells.aura", "ProcDamageAndSpell: casting spell {} (triggered by {} aura of spell {})", spellInfo->Id, (isVictim ? "a victim's" : "an attacker's"), triggeredByAura->GetId());
16442 // Don`t drop charge or add cooldown for not started trigger
16443 if (HandleProcTriggerSpell(target, damage, triggeredByAura, procSpellInfo, procFlag, procExtra, cooldown, procPhase, eventInfo))
16444 takeCharges = true;
16445 break;
16446 }
16448 {
16449 // target has to be valid
16450 if (!eventInfo.GetProcTarget())
16451 break;
16452
16453 triggeredByAura->HandleProcTriggerDamageAuraProc(aurApp, eventInfo); // this function is part of the new proc system
16454 takeCharges = true;
16455 break;
16456 }
16458 case SPELL_AURA_DUMMY:
16459 {
16460 LOG_DEBUG("spells.aura", "ProcDamageAndSpell: casting spell id {} (triggered by {} dummy aura of spell {})", spellInfo->Id, (isVictim ? "a victim's" : "an attacker's"), triggeredByAura->GetId());
16461 if (HandleDummyAuraProc(target, damage, triggeredByAura, procSpellInfo, procFlag, procExtra, cooldown, procSpell))
16462 takeCharges = true;
16463 break;
16464 }
16469 LOG_DEBUG("spells.aura", "ProcDamageAndSpell: casting spell id {} (triggered by {} aura of spell {})", spellInfo->Id, isVictim ? "a victim's" : "an attacker's", triggeredByAura->GetId());
16470 takeCharges = true;
16471 break;
16473 {
16474 LOG_DEBUG("spells.aura", "ProcDamageAndSpell: casting spell id {} (triggered by {} aura of spell {})", spellInfo->Id, (isVictim ? "a victim's" : "an attacker's"), triggeredByAura->GetId());
16475 if (HandleOverrideClassScriptAuraProc(target, damage, triggeredByAura, procSpellInfo, cooldown))
16476 takeCharges = true;
16477 break;
16478 }
16480 {
16481 LOG_DEBUG("spells.aura", "ProcDamageAndSpell: casting mending (triggered by {} dummy aura of spell {})",
16482 (isVictim ? "a victim's" : "an attacker's"), triggeredByAura->GetId());
16483 if (damage > 0)
16484 {
16486 takeCharges = true;
16487 }
16488 break;
16489 }
16491 {
16492 LOG_DEBUG("spells.aura", "ProcDamageAndSpell: casting mending (triggered by {} dummy aura of spell {})",
16493 (isVictim ? "a victim's" : "an attacker's"), triggeredByAura->GetId());
16494 HandleAuraRaidProcFromCharge(triggeredByAura);
16495 takeCharges = true;
16496 break;
16497 }
16499 {
16500 LOG_DEBUG("spells.aura", "ProcDamageAndSpell: casting spell {} (triggered with value by {} aura of spell {})", spellInfo->Id, (isVictim ? "a victim's" : "an attacker's"), triggeredByAura->GetId());
16501
16502 if (HandleProcTriggerSpell(target, damage, triggeredByAura, procSpellInfo, procFlag, procExtra, cooldown, procPhase, eventInfo))
16503 takeCharges = true;
16504 break;
16505 }
16507 // Skip melee hits or instant cast spells
16508 // xinef: check channeled spells which are affected by haste also
16509 if (procSpellInfo && (procSpellInfo->SpellFamilyName || GetTypeId() != TYPEID_PLAYER) &&
16510 (procSpellInfo->CalcCastTime() > 0 /*||
16511 (procSpell->IsChanneled() && procSpell->GetDuration() > 0 && (HasAuraTypeWithAffectMask(SPELL_AURA_PERIODIC_HASTE, procSpell) || procSpell->HasAttribute(SPELL_ATTR5_SPELL_HASTE_AFFECTS_PERIODIC)))*/))
16512 takeCharges = true;
16513 break;
16515 // Skip Melee hits and spells ws wrong school
16516 if (procSpellInfo && (triggeredByAura->GetMiscValue() & procSpellInfo->SchoolMask)) // School check
16517 takeCharges = true;
16518 break;
16520 // Skip Melee hits and targets with magnet aura
16521 if (procSpellInfo && (triggeredByAura->GetBase()->GetUnitOwner()->ToUnit() == ToUnit())) // Magnet
16522 takeCharges = true;
16523 break;
16526 // Skip melee hits and spells ws wrong school or zero cost
16527 if (procSpellInfo &&
16528 (procSpellInfo->ManaCost != 0 || procSpellInfo->ManaCostPercentage != 0 || (procSpellInfo->SpellFamilyFlags[1] & 0x2)) && // Cost check, mutilate include
16529 (triggeredByAura->GetMiscValue() & procSpellInfo->SchoolMask)) // School check
16530 takeCharges = true;
16531 break;
16534 // Compare mechanic
16535 if (procSpellInfo && procSpellInfo->Mechanic == uint32(triggeredByAura->GetMiscValue()))
16536 takeCharges = true;
16537 break;
16539 // Compare casters
16540 if (target && triggeredByAura->GetCasterGUID() == target->GetGUID())
16541 takeCharges = true;
16542 break;
16543 // CC Auras which use their amount amount to drop
16544 // Are there any more auras which need this?
16550 {
16551 // Spell own direct damage at apply wont break the CC
16552 // Xinef: Or when the aura is at full duration (assume that such auras should be added at the end, skipping all damage procs etc.)
16553 if (procSpellInfo)
16554 if ((!i->aura->IsPermanent() && i->aura->GetDuration() == i->aura->GetMaxDuration()) || procSpellInfo->Id == triggeredByAura->GetId() ||
16555 procSpellInfo->HasAttribute(SPELL_ATTR4_REACTIVE_DAMAGE_PROC))
16556 break;
16557
16558 // chargeable mods are breaking on hit
16559 if (useCharges)
16560 takeCharges = true;
16561 else if (triggeredByAura->GetAmount()) // aura must have amount
16562 {
16563 int32 damageLeft = triggeredByAura->GetAmount();
16564 // No damage left
16565 if (damageLeft < int32(damage))
16566 i->aura->Remove();
16567 else
16568 triggeredByAura->SetAmount(damageLeft - damage);
16569 }
16570 break;
16571 }
16573 if (procSpellInfo && procSpellInfo->Id == 20647) // hack for warriors execute, both dummy and damage spell are affected by ignore aurastate aura
16574 break;
16575 takeCharges = true;
16576 break;
16579 {
16580 if (SpellModifier* mod = triggeredByAura->GetSpellModifier())
16581 {
16582 if (mod->op == SPELLMOD_CASTING_TIME && mod->value < 0 && procSpell)
16583 {
16584 // Skip instant spells
16585 if (procSpellInfo->CalcCastTime() <= 0 || (procSpell->GetTriggeredCastFlags() & TRIGGERED_CAST_DIRECTLY) != 0)
16586 {
16587 break;
16588 }
16589 }
16590 }
16591 takeCharges = true;
16592 break;
16593 }
16594 default:
16595 takeCharges = true;
16596 break;
16597 }
16598 i->aura->CallScriptAfterEffectProcHandlers(triggeredByAura, aurApp, eventInfo);
16599 }
16600 // Remove charge (aura can be removed by triggers)
16601 // xinef: take into account attribute6 of proc spell
16602 if (prepare && useCharges && takeCharges)
16603 if (!procSpellInfo || isVictim || !procSpellInfo->HasAttribute(SPELL_ATTR6_DO_NOT_CONSUME_RESOURCES))
16604 i->aura->DropCharge();
16605
16606 i->aura->CallScriptAfterProcHandlers(aurApp, eventInfo);
16607
16609 SetCantProc(false);
16610 }
16611
16612 // Cleanup proc requirements
16614 SetCantProc(false);
16615}
@ CONDITION_SOURCE_TYPE_SPELL_PROC
Definition: ConditionMgr.h:146
@ EFFECT_2
Definition: SharedDefines.h:32
@ SPELL_ATTR3_INSTANT_TARGET_PROCS
Definition: SharedDefines.h:484
#define EFFECT_ALL
Definition: SharedDefines.h:37
@ SPELL_ATTR6_DO_NOT_CONSUME_RESOURCES
Definition: SharedDefines.h:581
@ SPELL_AURA_RAID_PROC_FROM_CHARGE_WITH_VALUE
Definition: SpellAuraDefines.h:288
@ SPELL_AURA_ADD_PCT_MODIFIER
Definition: SpellAuraDefines.h:171
@ SPELL_AURA_OBS_MOD_POWER
Definition: SpellAuraDefines.h:84
@ SPELL_AURA_ADD_FLAT_MODIFIER
Definition: SpellAuraDefines.h:170
@ SPELL_AURA_MOD_SPELL_CRIT_CHANCE
Definition: SpellAuraDefines.h:120
@ SPELL_AURA_MOD_POWER_COST_SCHOOL_PCT
Definition: SpellAuraDefines.h:135
@ SPELL_AURA_MOD_POWER_COST_SCHOOL
Definition: SpellAuraDefines.h:136
@ SPELL_AURA_MECHANIC_IMMUNITY
Definition: SpellAuraDefines.h:140
@ SPELL_AURA_RAID_PROC_FROM_CHARGE
Definition: SpellAuraDefines.h:286
@ SPELL_AURA_PROC_TRIGGER_DAMAGE
Definition: SpellAuraDefines.h:106
@ SPELL_AURA_REFLECT_SPELLS_SCHOOL
Definition: SpellAuraDefines.h:137
@ SPELL_AURA_MOD_CASTING_SPEED_NOT_STACK
Definition: SpellAuraDefines.h:128
@ TRIGGERED_CAST_DIRECTLY
Will ignore combo point requirement.
Definition: SpellDefines.h:139
@ PROC_HIT_CRITICAL
Definition: SpellMgr.h:253
#define MELEE_BASED_TRIGGER_MASK
Definition: SpellMgr.h:182
@ PROC_EX_INTERNAL_CANT_PROC
Definition: SpellMgr.h:218
@ PROC_EX_RESIST
Definition: SpellMgr.h:197
@ PROC_EX_ABSORB
Definition: SpellMgr.h:204
@ PROC_EX_INTERNAL_TRIGGERED
Definition: SpellMgr.h:221
@ PROC_FLAG_DONE_PERIODIC
Definition: SpellMgr.h:134
static bool isNonTriggerAura[TOTAL_AURAS]
Definition: Unit.cpp:106
static bool isTriggerAura[TOTAL_AURAS]
Definition: Unit.cpp:104
std::list< ProcTriggeredData > ProcTriggeredList
Definition: Unit.cpp:15952
@ REACTIVE_OVERPOWER
Definition: Unit.h:1204
@ REACTIVE_DEFENSE
Definition: Unit.h:1202
@ REACTIVE_HUNTER_PARRY
Definition: Unit.h:1203
@ REACTIVE_WOLVERINE_BITE
Definition: Unit.h:1205
void HandleProcTriggerDamageAuraProc(AuraApplication *aurApp, ProcEventInfo &eventInfo)
Definition: SpellAuraEffects.cpp:6891
SpellModifier * GetSpellModifier() const
Definition: SpellAuraEffects.h:52
Unit * GetUnitOwner() const
Definition: SpellAuras.h:108
void UpdateCombatSkills(Unit *victim, WeaponAttackType attType, bool defence, Item *item=nullptr)
Definition: PlayerUpdates.cpp:981
Definition: Unit.h:839
void SetProcCooldown(uint32 cooldown)
Definition: Unit.h:873
Unit * GetActionTarget() const
Definition: Unit.h:859
Unit * GetProcTarget() const
Definition: Unit.h:860
bool HandleProcTriggerSpell(Unit *victim, uint32 damage, AuraEffect *triggeredByAura, SpellInfo const *procSpell, uint32 procFlag, uint32 procEx, uint32 cooldown, uint32 procPhase, ProcEventInfo &eventInfo)
Definition: Unit.cpp:8873
bool HandleAuraRaidProcFromChargeWithValue(AuraEffect *triggeredByAura)
Definition: Unit.cpp:17612
bool IsHunterPet() const
Definition: Unit.h:1414
bool IsTriggeredAtSpellProcEvent(Unit *victim, Aura *aura, WeaponAttackType attType, bool isVictim, bool active, SpellProcEventEntry const *&spellProcEvent, ProcEventInfo const &eventInfo)
Definition: Unit.cpp:17473
bool HandleAuraProc(Unit *victim, uint32 damage, Aura *triggeredByAura, SpellInfo const *procSpell, uint32 procFlag, uint32 procEx, uint32 cooldown, bool *handled)
Definition: Unit.cpp:8678
virtual bool HasSpellItemCooldown(uint32, uint32) const
Definition: Unit.h:2414
void StartReactiveTimer(ReactiveType reactive)
Definition: Unit.h:2308
bool HandleOverrideClassScriptAuraProc(Unit *victim, uint32 damage, AuraEffect *triggeredByAura, SpellInfo const *procSpell, uint32 cooldown)
Definition: Unit.cpp:9822
bool HandleDummyAuraProc(Unit *victim, uint32 damage, AuraEffect *triggeredByAura, SpellInfo const *procSpell, uint32 procFlag, uint32 procEx, uint32 cooldown, Spell const *spellProc=nullptr)
Definition: Unit.cpp:6489
bool HandleAuraRaidProcFromCharge(AuraEffect *triggeredByAura)
Definition: Unit.cpp:17701
bool IsCharmedOwnedByPlayerOrPlayer() const
Definition: Unit.h:1835
Definition: Unit.cpp:15933
Definition: Player.h:182

◆ processDummyAuras()

float Unit::processDummyAuras ( float  TakenTotalMod) const
private
11814{
11815 // note: old code coming from TC, just extracted here to remove the code duplication + solve potential crash
11816 // see: https://github.com/TrinityCore/TrinityCore/commit/c85710e148d75450baedf6632b9ca6fd40b4148e
11817
11818 // .. taken pct: dummy auras
11819 auto const& mDummyAuras = GetAuraEffectsByType(SPELL_AURA_DUMMY);
11820 for (auto i = mDummyAuras.begin(); i != mDummyAuras.end(); ++i)
11821 {
11822 if (!(*i) || !(*i)->GetSpellInfo())
11823 {
11824 continue;
11825 }
11826
11827 if (auto spellIconId = (*i)->GetSpellInfo()->SpellIconID)
11828 {
11829 switch (spellIconId)
11830 {
11831 // Cheat Death
11832 case 2109:
11833 if ((*i)->GetMiscValue() & SPELL_SCHOOL_MASK_NORMAL)
11834 {
11835 // Patch 2.4.3: The resilience required to reach the 90% damage reduction cap
11836 // is 22.5% critical strike damage reduction, or 444 resilience.
11837 // To calculate for 90%, we multiply the 100% by 4 (22.5% * 4 = 90%)
11838 float mod = -1.0f * GetMeleeCritDamageReduction(400);
11839 AddPct(TakenTotalMod, std::max(mod, float((*i)->GetAmount())));
11840 }
11841 break;
11842 }
11843 }
11844 }
11845 return TakenTotalMod;
11846}

◆ ProcessPositionDataChanged()

void Unit::ProcessPositionDataChanged ( PositionFullTerrainStatus const &  data)
overridevirtual

Reimplemented from WorldObject.

4183{
4186}
virtual void ProcessTerrainStatusUpdate()
Definition: Unit.cpp:4188
virtual void ProcessPositionDataChanged(PositionFullTerrainStatus const &data)
Definition: Object.cpp:1163

◆ ProcessTerrainStatusUpdate()

void Unit::ProcessTerrainStatusUpdate ( )
virtual

Reimplemented in Player.

4189{
4190 if (GetTypeId() == TYPEID_UNIT)
4192
4193 if (IsFlying() || (!IsControlledByPlayer()))
4194 return;
4195
4196 LiquidData const& liquidData = GetLiquidData();
4197
4198 // remove appropriate auras if we are swimming/not swimming respectively
4199 if (liquidData.Status & MAP_LIQUID_STATUS_SWIMMING)
4201 else
4203
4204 // liquid aura handling
4205 LiquidTypeEntry const* curLiquid = nullptr;
4206 if ((liquidData.Status & MAP_LIQUID_STATUS_SWIMMING))
4207 curLiquid = sLiquidTypeStore.LookupEntry(liquidData.Entry);
4208
4209 if (curLiquid != _lastLiquid)
4210 {
4213
4214 // Set _lastLiquid before casting liquid spell to avoid infinite loops
4215 _lastLiquid = curLiquid;
4216
4218 if (curLiquid && curLiquid->SpellId && (!player || !player->IsGameMaster()))
4219 CastSpell(this, curLiquid->SpellId, true);
4220 }
4221}
DBCStorage< LiquidTypeEntry > sLiquidTypeStore(LiquidTypefmt)
@ AURA_INTERRUPT_FLAG_NOT_ABOVEWATER
Definition: SpellDefines.h:51
@ AURA_INTERRUPT_FLAG_NOT_UNDERWATER
Definition: SpellDefines.h:52
void UpdateMovementFlags()
Definition: Creature.cpp:3295
bool IsFlying() const
Definition: Unit.h:2380
Definition: Map.h:170
uint32 Entry
Definition: Map.h:173
Definition: DBCStructure.h:1266
uint32 SpellId
Definition: DBCStructure.h:1272

◆ ProhibitSpellSchool()

virtual void Unit::ProhibitSpellSchool ( SpellSchoolMask  ,
uint32   
)
inlinevirtual

Reimplemented in Creature, and Player.

2045{ }

◆ propagateSpeedChange()

void Unit::propagateSpeedChange ( )
inline

-------—End of Pet responses methods-------—

void propagateSpeedChange()
Definition: MotionMaster.cpp:794

◆ RemoveAllAttackers()

void Unit::RemoveAllAttackers ( )
10433{
10434 while (!m_attackers.empty())
10435 {
10436 AttackerSet::iterator iter = m_attackers.begin();
10437 if (!(*iter)->AttackStop())
10438 {
10439 LOG_ERROR("entities.unit", "WORLD: Unit has an attacker that isn't attacking it!");
10440 m_attackers.erase(iter);
10441 }
10442 }
10443}

◆ RemoveAllAuras()

void Unit::RemoveAllAuras ( )
5228{
5229 // this may be a dead loop if some events on aura remove will continiously apply aura on remove
5230 // we want to have all auras removed, so use your brain when linking events
5231 while (!m_appliedAuras.empty() || !m_ownedAuras.empty())
5232 {
5233 AuraApplicationMap::iterator aurAppIter;
5234 for (aurAppIter = m_appliedAuras.begin(); aurAppIter != m_appliedAuras.end();)
5236
5237 AuraMap::iterator aurIter;
5238 for (aurIter = m_ownedAuras.begin(); aurIter != m_ownedAuras.end();)
5239 RemoveOwnedAura(aurIter);
5240 }
5241}

◆ RemoveAllAurasExceptType()

void Unit::RemoveAllAurasExceptType ( AuraType  type)
5302{
5303 for (AuraApplicationMap::iterator iter = m_appliedAuras.begin(); iter != m_appliedAuras.end();)
5304 {
5305 Aura const* aura = iter->second->GetBase();
5306 if (aura->GetSpellInfo()->HasAura(type))
5307 ++iter;
5308 else
5310 }
5311
5312 for (AuraMap::iterator iter = m_ownedAuras.begin(); iter != m_ownedAuras.end();)
5313 {
5314 Aura* aura = iter->second;
5315 if (aura->GetSpellInfo()->HasAura(type))
5316 ++iter;
5317 else
5319 }
5320}

◆ RemoveAllAurasOnDeath()

void Unit::RemoveAllAurasOnDeath ( )
5258{
5259 // used just after dieing to remove all visible auras
5260 // and disable the mods for the passive ones
5261 for (AuraApplicationMap::iterator iter = m_appliedAuras.begin(); iter != m_appliedAuras.end();)
5262 {
5263 Aura const* aura = iter->second->GetBase();
5266 else
5267 ++iter;
5268 }
5269
5270 for (AuraMap::iterator iter = m_ownedAuras.begin(); iter != m_ownedAuras.end();)
5271 {
5272 Aura* aura = iter->second;
5275 else
5276 ++iter;
5277 }
5278}
@ SPELL_ATTR7_DISABLE_AURA_WHILE_DEAD
Definition: SharedDefines.h:615
@ AURA_REMOVE_BY_DEATH
Definition: SpellAuraDefines.h:396
bool IsDeathPersistent() const
Definition: SpellAuras.cpp:1101

◆ RemoveAllAurasRequiringDeadTarget()

void Unit::RemoveAllAurasRequiringDeadTarget ( )
5281{
5282 for (AuraApplicationMap::iterator iter = m_appliedAuras.begin(); iter != m_appliedAuras.end();)
5283 {
5284 Aura const* aura = iter->second->GetBase();
5285 if (!aura->IsPassive() && aura->GetSpellInfo()->IsRequiringDeadTarget())
5287 else
5288 ++iter;
5289 }
5290
5291 for (AuraMap::iterator iter = m_ownedAuras.begin(); iter != m_ownedAuras.end();)
5292 {
5293 Aura* aura = iter->second;
5294 if (!aura->IsPassive() && aura->GetSpellInfo()->IsRequiringDeadTarget())
5296 else
5297 ++iter;
5298 }
5299}
bool IsRequiringDeadTarget() const
Definition: SpellInfo.cpp:1205

◆ RemoveAllControlled()

void Unit::RemoveAllControlled ( bool  onDeath = false)
11035{
11036 // possessed pet and vehicle
11037 if (GetTypeId() == TYPEID_PLAYER)
11039
11040 while (!m_Controlled.empty())
11041 {
11042 Unit* target = *m_Controlled.begin();
11043 m_Controlled.erase(m_Controlled.begin());
11044 if (target->GetCharmerGUID() == GetGUID())
11045 {
11046 target->RemoveCharmAuras();
11047 }
11048 else if (target->GetOwnerGUID() == GetGUID() && target->IsSummon())
11049 {
11050 if (!(onDeath && !IsPlayer() && target->IsGuardian()))
11051 {
11052 target->ToTempSummon()->UnSummon();
11053 }
11054 }
11055 else
11056 {
11057 LOG_ERROR("entities.unit", "Unit {} is trying to release unit {} which is neither charmed nor owned by it", GetEntry(), target->GetEntry());
11058 }
11059 }
11060}
void StopCastingCharm()
Definition: Player.cpp:9166
bool IsGuardian() const
Definition: Unit.h:1411
void RemoveCharmAuras()
Definition: Unit.cpp:11145

◆ RemoveAllDynObjects()

void Unit::RemoveAllDynObjects ( )
6064{
6065 while (!m_dynObj.empty())
6066 m_dynObj.front()->Remove();
6067}

◆ RemoveAllGameObjects()

void Unit::RemoveAllGameObjects ( )
6164{
6165 while(!m_gameObj.empty())
6166 {
6167 GameObject* go = ObjectAccessor::GetGameObject(*this, *m_gameObj.begin());
6168 if(go)
6169 {
6171 go->SetRespawnTime(0);
6172 go->Delete();
6173 }
6174 m_gameObj.erase(m_gameObj.begin());
6175 }
6176}
void Delete()
Definition: GameObject.cpp:949
void SetRespawnTime(int32 respawn)
Definition: GameObject.cpp:1274

◆ RemoveAllMinionsByEntry()

void Unit::RemoveAllMinionsByEntry ( uint32  entry)
10812{
10813 for (Unit::ControlSet::iterator itr = m_Controlled.begin(); itr != m_Controlled.end();)
10814 {
10815 Unit* unit = *itr;
10816 ++itr;
10817 if (unit->GetEntry() == entry && unit->GetTypeId() == TYPEID_UNIT
10818 && unit->ToCreature()->IsSummon()) // minion, actually
10819 unit->ToTempSummon()->UnSummon();
10820 // i think this is safe because i have never heard that a despawned minion will trigger a same minion
10821 }
10822}

◆ RemoveAppliedAuras() [1/2]

void Unit::RemoveAppliedAuras ( std::function< bool(AuraApplication const *)> const &  check)
4785{
4786 for (AuraApplicationMap::iterator iter = m_appliedAuras.begin(); iter != m_appliedAuras.end();)
4787 {
4788 if (check(iter->second))
4789 {
4790 RemoveAura(iter);
4791 continue;
4792 }
4793 ++iter;
4794 }
4795}

◆ RemoveAppliedAuras() [2/2]

void Unit::RemoveAppliedAuras ( uint32  spellId,
std::function< bool(AuraApplication const *)> const &  check 
)
4811{
4812 for (AuraApplicationMap::iterator iter = m_appliedAuras.lower_bound(spellId); iter != m_appliedAuras.upper_bound(spellId);)
4813 {
4814 if (check(iter->second))
4815 {
4816 RemoveAura(iter);
4817 continue;
4818 }
4819 ++iter;
4820 }
4821}

◆ RemoveAreaAurasDueToLeaveWorld()

void Unit::RemoveAreaAurasDueToLeaveWorld ( )
5195{
5196 // make sure that all area auras not applied on self are removed - prevent access to deleted pointer later
5197 for (AuraMap::iterator iter = m_ownedAuras.begin(); iter != m_ownedAuras.end();)
5198 {
5199 Aura* aura = iter->second;
5200 ++iter;
5201 Aura::ApplicationMap const& appMap = aura->GetApplicationMap();
5202 for (Aura::ApplicationMap::const_iterator itr = appMap.begin(); itr != appMap.end();)
5203 {
5204 AuraApplication* aurApp = itr->second;
5205 ++itr;
5206 Unit* target = aurApp->GetTarget();
5207 if (target == this)
5208 continue;
5209 target->RemoveAura(aurApp);
5210 // things linked on aura remove may apply new area aura - so start from the beginning
5211 iter = m_ownedAuras.begin();
5212 }
5213 }
5214
5215 // remove area auras owned by others
5216 for (AuraApplicationMap::iterator iter = m_appliedAuras.begin(); iter != m_appliedAuras.end();)
5217 {
5218 if (iter->second->GetBase()->GetOwner() != this)
5219 {
5220 RemoveAura(iter);
5221 }
5222 else
5223 ++iter;
5224 }
5225}
ApplicationMap const & GetApplicationMap()
Definition: SpellAuras.h:181
std::map< ObjectGuid, AuraApplication * > ApplicationMap
Definition: SpellAuras.h:90

◆ RemoveArenaAuras()

void Unit::RemoveArenaAuras ( )
5244{
5245 // in join, remove positive buffs, on end, remove negative
5246 // used to remove positive visible auras in arenas
5247 RemoveAppliedAuras([](AuraApplication const* aurApp)
5248 {
5249 Aura const* aura = aurApp->GetBase();
5250 return (!aura->GetSpellInfo()->HasAttribute(SPELL_ATTR4_ALLOW_ENETRING_ARENA) // don't remove stances, shadowform, pally/hunter auras
5251 && !aura->IsPassive() // don't remove passive auras
5252 && (aurApp->IsPositive() || !aura->GetSpellInfo()->HasAttribute(SPELL_ATTR3_ALLOW_AURA_WHILE_DEAD))) || // not negative death persistent auras
5253 aura->GetSpellInfo()->HasAttribute(SPELL_ATTR5_REMOVE_ENTERING_ARENA); // special marker, always remove
5254 });
5255}
@ SPELL_ATTR5_REMOVE_ENTERING_ARENA
Definition: SharedDefines.h:541
@ SPELL_ATTR3_ALLOW_AURA_WHILE_DEAD
Definition: SharedDefines.h:485
@ SPELL_ATTR4_ALLOW_ENETRING_ARENA
Definition: SharedDefines.h:523
bool IsPositive() const
Definition: SpellAuras.h:68
void RemoveAppliedAuras(std::function< bool(AuraApplication const *)> const &check)
Definition: Unit.cpp:4784

◆ RemoveAura() [1/4]

void Unit::RemoveAura ( Aura aur,
AuraRemoveMode  mode = AURA_REMOVE_BY_DEFAULT 
)
4764{
4765 if (aura->IsRemoved())
4766 return;
4767 if (AuraApplication* aurApp = aura->GetApplicationOfTarget(GetGUID()))
4768 RemoveAura(aurApp, mode);
4769}

◆ RemoveAura() [2/4]

void Unit::RemoveAura ( AuraApplication aurApp,
AuraRemoveMode  mode = AURA_REMOVE_BY_DEFAULT 
)
4729{
4730 // we've special situation here, RemoveAura called while during aura removal
4731 // this kind of call is needed only when aura effect removal handler
4732 // or event triggered by it expects to remove
4733 // not yet removed effects of an aura
4734 if (aurApp->GetRemoveMode())
4735 {
4736 // remove remaining effects of an aura
4737 for (uint8 itr = 0; itr < MAX_SPELL_EFFECTS; ++itr)
4738 {
4739 if (aurApp->HasEffect(itr))
4740 aurApp->_HandleEffect(itr, false);
4741 }
4742 return;
4743 }
4744 // no need to remove
4745 if (aurApp->GetBase()->GetApplicationOfTarget(GetGUID()) != aurApp || aurApp->GetBase()->IsRemoved())
4746 return;
4747
4748 uint32 spellId = aurApp->GetBase()->GetId();
4749 AuraApplicationMapBoundsNonConst range = m_appliedAuras.equal_range(spellId);
4750
4751 for (AuraApplicationMap::iterator iter = range.first; iter != range.second;)
4752 {
4753 if (aurApp == iter->second)
4754 {
4755 RemoveAura(iter, mode);
4756 return;
4757 }
4758 else
4759 ++iter;
4760 }
4761}

◆ RemoveAura() [3/4]

void Unit::RemoveAura ( AuraApplicationMap::iterator &  i,
AuraRemoveMode  mode = AURA_REMOVE_BY_DEFAULT 
)
4697{
4698 AuraApplication* aurApp = i->second;
4699 // Do not remove aura which is already being removed
4700 if (aurApp->GetRemoveMode())
4701 return;
4702 Aura* aura = aurApp->GetBase();
4703 _UnapplyAura(i, mode);
4704 // Remove aura - for Area and Target auras
4705 if (aura->GetOwner() == this)
4706 aura->Remove(mode);
4707
4708 sScriptMgr->OnAuraRemove(this, aurApp, mode);
4709}

◆ RemoveAura() [4/4]

void Unit::RemoveAura ( uint32  spellId,
ObjectGuid  casterGUID = ObjectGuid::Empty,
uint8  reqEffMask = 0,
AuraRemoveMode  removeMode = AURA_REMOVE_BY_DEFAULT 
)
4712{
4713 AuraApplicationMapBoundsNonConst range = m_appliedAuras.equal_range(spellId);
4714 for (AuraApplicationMap::iterator iter = range.first; iter != range.second;)
4715 {
4716 Aura const* aura = iter->second->GetBase();
4717 if (((aura->GetEffectMask() & reqEffMask) == reqEffMask)
4718 && (!caster || aura->GetCasterGUID() == caster))
4719 {
4720 RemoveAura(iter, removeMode);
4721 return;
4722 }
4723 else
4724 ++iter;
4725 }
4726}

◆ RemoveAuraFromStack()

void Unit::RemoveAuraFromStack ( uint32  spellId,
ObjectGuid  casterGUID = ObjectGuid::Empty,
AuraRemoveMode  removeMode = AURA_REMOVE_BY_DEFAULT 
)
4840{
4841 AuraMapBoundsNonConst range = m_ownedAuras.equal_range(spellId);
4842 for (AuraMap::iterator iter = range.first; iter != range.second;)
4843 {
4844 Aura* aura = iter->second;
4845 if ((aura->GetType() == UNIT_AURA_TYPE)
4846 && (!casterGUID || aura->GetCasterGUID() == casterGUID))
4847 {
4848 aura->ModStackAmount(-1, removeMode);
4849 return;
4850 }
4851 else
4852 ++iter;
4853 }
4854}
@ UNIT_AURA_TYPE
Definition: SpellAuraDefines.h:385
bool ModStackAmount(int32 num, AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT, bool periodicReset=false)
Definition: SpellAuras.cpp:1035
AuraObjectType GetType() const
Definition: SpellAuras.cpp:481

◆ RemoveAurasByShapeShift()

void Unit::RemoveAurasByShapeShift ( )
5179{
5180 uint32 mechanic_mask = (1 << MECHANIC_SNARE) | (1 << MECHANIC_ROOT);
5181 for (AuraApplicationMap::iterator iter = m_appliedAuras.begin(); iter != m_appliedAuras.end();)
5182 {
5183 Aura const* aura = iter->second->GetBase();
5184 if ((aura->GetSpellInfo()->GetAllEffectsMechanicMask() & mechanic_mask) &&
5186 {
5187 RemoveAura(iter);
5188 continue;
5189 }
5190 ++iter;
5191 }
5192}
@ SPELL_ATTR0_CU_AURA_CC
Definition: SpellInfo.h:181
uint32 GetAllEffectsMechanicMask() const
Definition: SpellInfo.cpp:1974

◆ RemoveAurasByType()

void Unit::RemoveAurasByType ( AuraType  auraType,
ObjectGuid  casterGUID = ObjectGuid::Empty,
Aura except = nullptr,
bool  negative = true,
bool  positive = true 
)
5014{
5015 // simple check if list is empty
5016 if (m_modAuras[auraType].empty())
5017 return;
5018
5019 for (AuraEffectList::iterator iter = m_modAuras[auraType].begin(); iter != m_modAuras[auraType].end();)
5020 {
5021 Aura* aura = (*iter)->GetBase();
5023
5024 ++iter;
5025 if (aura != except && (!casterGUID || aura->GetCasterGUID() == casterGUID)
5026 && ((negative && !aurApp->IsPositive()) || (positive && aurApp->IsPositive())))
5027 {
5028 uint32 removedAuras = m_removedAurasCount;
5029 RemoveAura(aurApp);
5030 if (m_removedAurasCount > removedAuras + 1)
5031 iter = m_modAuras[auraType].begin();
5032 }
5033 }
5034}

◆ RemoveAurasDueToItemSpell()

void Unit::RemoveAurasDueToItemSpell ( uint32  spellId,
ObjectGuid  castItemGuid 
)
5000{
5001 for (AuraApplicationMap::iterator iter = m_appliedAuras.lower_bound(spellId); iter != m_appliedAuras.upper_bound(spellId);)
5002 {
5003 if (iter->second->GetBase()->GetCastItemGUID() == castItemGuid)
5004 {
5005 RemoveAura(iter);
5006 iter = m_appliedAuras.lower_bound(spellId);
5007 }
5008 else
5009 ++iter;
5010 }
5011}

◆ RemoveAurasDueToSpell()

void Unit::RemoveAurasDueToSpell ( uint32  spellId,
ObjectGuid  casterGUID = ObjectGuid::Empty,
uint8  reqEffMask = 0,
AuraRemoveMode  removeMode = AURA_REMOVE_BY_DEFAULT 
)
4824{
4825 for (AuraApplicationMap::iterator iter = m_appliedAuras.lower_bound(spellId); iter != m_appliedAuras.upper_bound(spellId);)
4826 {
4827 Aura const* aura = iter->second->GetBase();
4828 if (((aura->GetEffectMask() & reqEffMask) == reqEffMask)
4829 && (!casterGUID || aura->GetCasterGUID() == casterGUID))
4830 {
4831 RemoveAura(iter, removeMode);
4832 iter = m_appliedAuras.lower_bound(spellId);
4833 }
4834 else
4835 ++iter;
4836 }
4837}

◆ RemoveAurasDueToSpellByDispel()

void Unit::RemoveAurasDueToSpellByDispel ( uint32  spellId,
uint32  dispellerSpellId,
ObjectGuid  casterGUID,
Unit dispeller,
uint8  chargesRemoved = 1 
)
4857{
4858 AuraMapBoundsNonConst range = m_ownedAuras.equal_range(spellId);
4859 for (AuraMap::iterator iter = range.first; iter != range.second;)
4860 {
4861 Aura* aura = iter->second;
4862 if (aura->GetCasterGUID() == casterGUID)
4863 {
4864 DispelInfo dispelInfo(dispeller, dispellerSpellId, chargesRemoved);
4865
4866 // Call OnDispel hook on AuraScript
4867 aura->CallScriptDispel(&dispelInfo);
4868
4870 aura->ModCharges(-dispelInfo.GetRemovedCharges(), AURA_REMOVE_BY_ENEMY_SPELL);
4871 else
4872 aura->ModStackAmount(-dispelInfo.GetRemovedCharges(), AURA_REMOVE_BY_ENEMY_SPELL);
4873
4874 // Call AfterDispel hook on AuraScript
4875 aura->CallScriptAfterDispel(&dispelInfo);
4876
4877 switch (aura->GetSpellInfo()->SpellFamilyName)
4878 {
4879 case SPELLFAMILY_HUNTER:
4880 {
4881 // Noxious Stings
4882 if (aura->GetSpellInfo()->SpellFamilyFlags[1] & 0x1000)
4883 {
4884 if (Unit* caster = aura->GetCaster())
4885 {
4886 if (AuraEffect* aureff = caster->GetAuraEffect(SPELL_AURA_OVERRIDE_CLASS_SCRIPTS, SPELLFAMILY_HUNTER, 3521, 1))
4887 {
4888 if (Aura* noxious = Aura::TryCreate(aura->GetSpellInfo(), aura->GetEffectMask(), dispeller, caster))
4889 {
4890 noxious->SetDuration(aura->GetDuration() * aureff->GetAmount() / 100);
4891 if (aura->GetUnitOwner() )
4892 if (const std::vector<int32>* spell_triggered = sSpellMgr->GetSpellLinked(-int32(aura->GetId())))
4893 for (std::vector<int32>::const_iterator itr = spell_triggered->begin(); itr != spell_triggered->end(); ++itr)
4894 aura->GetUnitOwner()->RemoveAurasDueToSpell(*itr);
4895 }
4896 }
4897 }
4898 }
4899 break;
4900 }
4902 {
4903 // Icy Clutch, remove with Frost Fever
4904 if (aura->GetSpellInfo()->SpellFamilyFlags[1] & 0x4000000)
4905 {
4906 if (AuraEffect* aureff = GetAuraEffect(SPELL_AURA_MOD_DECREASE_SPEED, SPELLFAMILY_DEATHKNIGHT, 0, 0x40000, 0, casterGUID))
4907 RemoveAurasDueToSpell(aureff->GetId());
4908 }
4909 }
4910 default:
4911 break;
4912 }
4913 return;
4914 }
4915 else
4916 ++iter;
4917 }
4918}
void CallScriptDispel(DispelInfo *dispelInfo)
Definition: SpellAuras.cpp:2394
static Aura * TryCreate(SpellInfo const *spellproto, uint8 effMask, WorldObject *owner, Unit *caster, int32 *baseAmount=nullptr, Item *castItem=nullptr, ObjectGuid casterGUID=ObjectGuid::Empty, ObjectGuid itemGUID=ObjectGuid::Empty)
Definition: SpellAuras.cpp:352
bool ModCharges(int32 num, AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT)
Definition: SpellAuras.cpp:987
void CallScriptAfterDispel(DispelInfo *dispelInfo)
Definition: SpellAuras.cpp:2407
Definition: Unit.h:727

◆ RemoveAurasDueToSpellBySteal()

void Unit::RemoveAurasDueToSpellBySteal ( uint32  spellId,
ObjectGuid  casterGUID,
Unit stealer 
)
4921{
4922 AuraMapBoundsNonConst range = m_ownedAuras.equal_range(spellId);
4923 for (AuraMap::iterator iter = range.first; iter != range.second;)
4924 {
4925 Aura* aura = iter->second;
4926 if (aura->GetCasterGUID() == casterGUID)
4927 {
4928 int32 damage[MAX_SPELL_EFFECTS];
4929 int32 baseDamage[MAX_SPELL_EFFECTS];
4930 uint8 effMask = 0;
4931 uint8 recalculateMask = 0;
4932 Unit* caster = aura->GetCaster();
4933 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
4934 {
4935 if (aura->GetEffect(i))
4936 {
4937 baseDamage[i] = aura->GetEffect(i)->GetBaseAmount();
4938 damage[i] = aura->GetEffect(i)->GetAmount();
4939 effMask |= (1 << i);
4940 if (aura->GetEffect(i)->CanBeRecalculated())
4941 recalculateMask |= (1 << i);
4942 }
4943 else
4944 {
4945 baseDamage[i] = 0;
4946 damage[i] = 0;
4947 }
4948 }
4949
4951 // Cast duration to unsigned to prevent permanent aura's such as Righteous Fury being permanently added to caster
4952 uint32 dur = std::min(2u * MINUTE * IN_MILLISECONDS, uint32(aura->GetDuration()));
4953
4954 if (Aura* oldAura = stealer->GetAura(aura->GetId(), aura->GetCasterGUID()))
4955 {
4956 if (stealCharge)
4957 oldAura->ModCharges(1);
4958 else
4959 oldAura->ModStackAmount(1);
4960 oldAura->SetDuration(int32(dur));
4961 }
4962 else
4963 {
4964 // single target state must be removed before aura creation to preserve existing single target aura
4965 if (aura->IsSingleTarget())
4966 aura->UnregisterSingleTarget();
4967
4968 // Xinef: if stealer has same aura
4969 Aura* curAura = stealer->GetAura(aura->GetId());
4970 if (!curAura || (!curAura->IsPermanent() && curAura->GetDuration() < (int32)dur))
4971 if (Aura* newAura = Aura::TryRefreshStackOrCreate(aura->GetSpellInfo(), effMask, stealer, nullptr, &baseDamage[0], nullptr, aura->GetCasterGUID()))
4972 {
4973 // created aura must not be single target aura,, so stealer won't loose it on recast
4974 if (newAura->IsSingleTarget())
4975 {
4976 newAura->UnregisterSingleTarget();
4977 // bring back single target aura status to the old aura
4978 aura->SetIsSingleTarget(true);
4979 caster->GetSingleCastAuras().push_back(aura);
4980 }
4981 // FIXME: using aura->GetMaxDuration() maybe not blizzlike but it fixes stealing of spells like Innervate
4982 newAura->SetLoadedState(aura->GetMaxDuration(), int32(dur), stealCharge ? 1 : aura->GetCharges(), 1, recalculateMask, &damage[0]);
4983 newAura->ApplyForTargets();
4984 }
4985 }
4986
4987 if (stealCharge)
4989 else
4991
4992 return;
4993 }
4994 else
4995 ++iter;
4996 }
4997}
bool CanBeRecalculated() const
Definition: SpellAuraEffects.h:77
int32 GetBaseAmount() const
Definition: SpellAuraEffects.h:57
void UnregisterSingleTarget()
Definition: SpellAuras.cpp:1181
bool IsPermanent() const
Definition: SpellAuras.h:139

◆ RemoveAurasWithAttribute()

void Unit::RemoveAurasWithAttribute ( uint32  flags)
5037{
5038 for (AuraApplicationMap::iterator iter = m_appliedAuras.begin(); iter != m_appliedAuras.end();)
5039 {
5040 SpellInfo const* spell = iter->second->GetBase()->GetSpellInfo();
5041 if (spell->Attributes & flags)
5042 RemoveAura(iter);
5043 else
5044 ++iter;
5045 }
5046}

◆ RemoveAurasWithFamily()

void Unit::RemoveAurasWithFamily ( SpellFamilyNames  family,
uint32  familyFlag1,
uint32  familyFlag2,
uint32  familyFlag3,
ObjectGuid  casterGUID 
)
5120{
5121 for (AuraApplicationMap::iterator iter = m_appliedAuras.begin(); iter != m_appliedAuras.end();)
5122 {
5123 Aura const* aura = iter->second->GetBase();
5124 if (!casterGUID || aura->GetCasterGUID() == casterGUID)
5125 {
5126 SpellInfo const* spell = aura->GetSpellInfo();
5127 if (spell->SpellFamilyName == uint32(family) && spell->SpellFamilyFlags.HasFlag(familyFlag1, familyFlag2, familyFlag3))
5128 {
5129 RemoveAura(iter);
5130 continue;
5131 }
5132 }
5133 ++iter;
5134 }
5135}

◆ RemoveAurasWithInterruptFlags()

void Unit::RemoveAurasWithInterruptFlags ( uint32  flag,
uint32  except = 0,
bool  isAutoshot = false 
)
5085{
5086 if (!(m_interruptMask & flag))
5087 return;
5088
5089 // interrupt auras
5090 for (AuraApplicationList::iterator iter = m_interruptableAuras.begin(); iter != m_interruptableAuras.end();)
5091 {
5092 Aura* aura = (*iter)->GetBase();
5093 ++iter;
5094 if ((aura->GetSpellInfo()->AuraInterruptFlags & flag) && (!except || aura->GetId() != except))
5095 {
5096 uint32 removedAuras = m_removedAurasCount;
5097 RemoveAura(aura);
5098 if (m_removedAurasCount > removedAuras + 1)
5099 iter = m_interruptableAuras.begin();
5100 }
5101 }
5102
5103 // interrupt channeled spell
5105 {
5106 if (spell->getState() == SPELL_STATE_CASTING && (spell->m_spellInfo->ChannelInterruptFlags & flag) && spell->m_spellInfo->Id != except)
5107 {
5108 // Do not interrupt if auto shot
5109 if (!(isAutoshot && spell->m_spellInfo->HasAttribute(SPELL_ATTR2_DO_NOT_RESET_COMBAT_TIMERS)))
5110 {
5111 InterruptNonMeleeSpells(false, spell->m_spellInfo->Id);
5112 }
5113 }
5114 }
5115
5117}

◆ RemoveAurasWithMechanic()

void Unit::RemoveAurasWithMechanic ( uint32  mechanic_mask,
AuraRemoveMode  removemode = AURA_REMOVE_BY_DEFAULT,
uint32  except = 0 
)
5162{
5163 for (AuraApplicationMap::iterator iter = m_appliedAuras.begin(); iter != m_appliedAuras.end();)
5164 {
5165 Aura const* aura = iter->second->GetBase();
5166 if (!except || aura->GetId() != except)
5167 {
5168 if (aura->GetSpellInfo()->GetAllEffectsMechanicMask() & mechanic_mask)
5169 {
5170 RemoveAura(iter, removemode);
5171 continue;
5172 }
5173 }
5174 ++iter;
5175 }
5176}

◆ RemoveBindSightAuras()

void Unit::RemoveBindSightAuras ( )
11141{
11143}
@ SPELL_AURA_BIND_SIGHT
Definition: SpellAuraDefines.h:64

◆ RemoveCharmAuras()

void Unit::RemoveCharmAuras ( )
11146{
11151}
@ SPELL_AURA_MOD_POSSESS_PET
Definition: SpellAuraDefines.h:191
@ SPELL_AURA_MOD_CHARM
Definition: SpellAuraDefines.h:69
@ SPELL_AURA_AOE_CHARM
Definition: SpellAuraDefines.h:240
@ SPELL_AURA_MOD_POSSESS
Definition: SpellAuraDefines.h:65

◆ RemoveCharmedBy()

void Unit::RemoveCharmedBy ( Unit charmer)
18585{
18586 if (!IsCharmed())
18587 return;
18588
18589 if (!charmer)
18590 charmer = GetCharmer();
18591 if (charmer != GetCharmer()) // one aura overrides another?
18592 {
18593 // LOG_FATAL("entities.unit", "Unit::RemoveCharmedBy: this: {} true charmer: {} false charmer: {}",
18594 // GetGUID().ToString(), GetCharmerGUID().ToString(), charmer->GetGUID().ToString());
18595 // ABORT();
18596 return;
18597 }
18598
18599 CharmType type;
18601 type = CHARM_TYPE_POSSESS;
18602 else if (charmer && charmer->IsOnVehicle(this))
18603 type = CHARM_TYPE_VEHICLE;
18604 else
18605 type = CHARM_TYPE_CHARM;
18606
18607 if (_oldFactionId)
18608 {
18610 _oldFactionId = 0;
18611 }
18612 else
18614
18615 CastStop();
18616 AttackStop();
18617
18618 // xinef: update speed after charming
18619 UpdateSpeed(MOVE_RUN, false);
18620
18621 // xinef: do not break any controlled motion slot
18622 if (GetMotionMaster()->GetMotionSlotType(MOTION_SLOT_CONTROLLED) == NULL_MOTION_TYPE)
18623 {
18624 StopMoving();
18626 }
18627 // xinef: if we have any controlled movement, clear active and idle only
18628 else
18630
18632
18633 // xinef: remove stunned flag if owner was mounted
18636
18637 // If charmer still exists
18638 if (!charmer)
18639 return;
18640
18641 ASSERT(type != CHARM_TYPE_POSSESS || charmer->GetTypeId() == TYPEID_PLAYER);
18643
18644 charmer->SetCharm(this, false);
18645
18647
18648 Player* playerCharmer = charmer->ToPlayer();
18649 if (playerCharmer)
18650 {
18651 switch (type)
18652 {
18653 case CHARM_TYPE_VEHICLE:
18654 playerCharmer->SetClientControl(this, false);
18655 playerCharmer->SetClientControl(charmer, true); // verified
18658 break;
18659 case CHARM_TYPE_POSSESS:
18660 playerCharmer->SetClientControl(this, false);
18661 playerCharmer->SetClientControl(charmer, true); // verified
18666 break;
18667 case CHARM_TYPE_CHARM:
18668 if (GetTypeId() == TYPEID_UNIT && charmer->getClass() == CLASS_WARLOCK)
18669 {
18671 if (cinfo && cinfo->type == CREATURE_TYPE_DEMON)
18672 {
18674 if (GetCharmInfo())
18675 GetCharmInfo()->SetPetNumber(0, true);
18676 else
18677 LOG_ERROR("entities.unit", "Aura::HandleModCharm: target={} has a charm aura but no charm info!", GetGUID().ToString());
18678 }
18679 }
18680 break;
18681 default:
18682 break;
18683 }
18684 }
18685
18686 if (Player* player = ToPlayer())
18687 {
18688 sScriptMgr->AnticheatSetUnderACKmount(player);
18689 }
18690
18691 // xinef: restore threat
18692 for (CharmThreatMap::const_iterator itr = _charmThreatInfo.begin(); itr != _charmThreatInfo.end(); ++itr)
18693 {
18694 if (Unit* target = ObjectAccessor::GetUnit(*this, itr->first))
18695 if (!IsFriendlyTo(target))
18696 AddThreat(target, itr->second);
18697 }
18698
18699 _charmThreatInfo.clear();
18700
18701 if (Creature* creature = ToCreature())
18702 {
18703 // Vehicle should not attack its passenger after he exists the seat
18704 if (type != CHARM_TYPE_VEHICLE && charmer->IsAlive() && !charmer->IsFriendlyTo(creature))
18705 if (Attack(charmer, true))
18706 GetMotionMaster()->MoveChase(charmer);
18707
18708 // Creature will restore its old AI on next update
18709 if (creature->AI())
18710 creature->AI()->OnCharmed(false);
18711
18712 // Xinef: Remove movement flag flying
18714 }
18715 else
18716 ToPlayer()->SetClientControl(this, true); // verified
18717
18718 // a guardian should always have charminfo
18719 if (playerCharmer && this != charmer->GetFirstControlled())
18720 playerCharmer->SendRemoveControlBar();
18721
18722 // xinef: Always delete charm info (restores react state)
18725}
@ MOTION_SLOT_CONTROLLED
Definition: MotionMaster.h:63
@ MOTION_SLOT_ACTIVE
Definition: MotionMaster.h:62
@ NULL_MOTION_TYPE
Definition: MotionMaster.h:56
@ CREATURE_TYPE_DEMON
Definition: SharedDefines.h:2602
CharmType
Definition: Unit.h:1074
@ CHARM_TYPE_CHARM
Definition: Unit.h:1075
@ CHARM_TYPE_POSSESS
Definition: Unit.h:1076
@ CHARM_TYPE_VEHICLE
Definition: Unit.h:1077
@ UNIT_STATE_NO_ENVIRONMENT_UPD
Definition: Unit.h:353
@ MOVE_RUN
Definition: Unit.h:379
@ UNIT_FLAG_DISABLE_MOVE
Definition: Unit.h:450
void InitDefault()
Definition: MotionMaster.cpp:86
void MovementExpiredOnSlot(MovementSlot slot, bool reset=true)
Definition: MotionMaster.h:192
void MovementExpired(bool reset=true)
Definition: MotionMaster.h:178
void SetByteValue(uint16 index, uint8 offset, uint8 value)
Definition: Object.cpp:750
void SendRemoveControlBar()
Definition: Player.cpp:9560
void SetClientControl(Unit *target, bool allowMove, bool packetOnly=false)
Definition: Player.cpp:12564
void DeleteCharmInfo()
Definition: Unit.cpp:15657
void RestoreFaction()
Definition: Unit.cpp:18727
void SetCharm(Unit *target, bool apply)
Definition: Unit.cpp:10824
void StopAttackingInvalidTarget()
Definition: Unit.cpp:20207
void CastStop(uint32 except_spellid=0, bool withInstant=true)
Definition: Unit.cpp:1161
bool Attack(Unit *victim, bool meleeAttack)
Definition: Unit.cpp:10233
CharmThreatMap _charmThreatInfo
Definition: Unit.h:2525
void RemoveUnitMovementFlag(uint32 f)
Definition: Unit.h:2268
void UpdateSpeed(UnitMoveType mtype, bool forced)
Definition: Unit.cpp:14135
uint32 unit_class
Definition: CreatureData.h:206

◆ RemoveComboPointHolder()

void Unit::RemoveComboPointHolder ( Unit unit)
inline
2295{ m_ComboPointHolders.erase(unit); }

◆ RemoveDynObject()

bool Unit::RemoveDynObject ( uint32  spellId)
6042{
6043 if (m_dynObj.empty())
6044 return false;
6045
6046 bool result = false;
6047 for (DynObjectList::iterator i = m_dynObj.begin(); i != m_dynObj.end();)
6048 {
6049 DynamicObject* dynObj = *i;
6050 if (dynObj->GetSpellId() == spellId)
6051 {
6052 dynObj->Remove();
6053 i = m_dynObj.begin();
6054 result = true;
6055 }
6056 else
6057 ++i;
6058 }
6059
6060 return result;
6061}
void Remove()
Definition: DynamicObject.cpp:189

◆ RemoveEvadeAuras()

void Unit::RemoveEvadeAuras ( )
5346{
5347 for (AuraApplicationMap::iterator iter = m_appliedAuras.begin(); iter != m_appliedAuras.end();)
5348 {
5349 Aura const* aura = iter->second->GetBase();
5350 SpellInfo const* spellInfo = aura->GetSpellInfo();
5352 ++iter;
5353 else
5355 }
5356
5357 for (AuraMap::iterator iter = m_ownedAuras.begin(); iter != m_ownedAuras.end();)
5358 {
5359 Aura* aura = iter->second;
5360 SpellInfo const* spellInfo = aura->GetSpellInfo();
5362 ++iter;
5363 else
5365 }
5366}
@ SPELL_AURA_CLONE_CASTER
Definition: SpellAuraDefines.h:310
@ SPELL_ATTR0_CU_IGNORE_EVADE
Definition: SpellInfo.h:187

◆ RemoveExtraUnitMovementFlag()

void Unit::RemoveExtraUnitMovementFlag ( uint16  f)
inline
2274{ m_movementInfo.flags2 &= ~f; }

◆ removeFollower()

void Unit::removeFollower ( FollowerReference )
inline
2255{ /* nothing to do yet */ }

◆ RemoveFromWorld()

void Unit::RemoveFromWorld ( )
overridevirtual

Reimplemented from WorldObject.

15534{
15535 // cleanup
15536 ASSERT(GetGUID());
15537
15538 if (IsInWorld())
15539 {
15541 if (IsVehicle())
15543
15547
15550
15551 ExitVehicle(); // Remove applied auras with SPELL_AURA_CONTROL_VEHICLE
15554
15556
15557 if (GetCharmerGUID())
15558 {
15559 LOG_FATAL("entities.unit", "Unit {} has charmer guid when removed from world", GetEntry());
15560 ABORT();
15561 }
15562
15563 if (Unit* owner = GetOwner())
15564 {
15565 if (owner->m_Controlled.find(this) != owner->m_Controlled.end())
15566 {
15568 owner->SetMinion((Minion*)this, false);
15569 LOG_INFO("entities.unit", "Unit {} is in controlled list of {} when removed from world", GetEntry(), owner->GetEntry());
15570 //ABORT();
15571 }
15572 }
15573
15576 }
15577}
void RemoveNotOwnSingleTargetAuras()
Definition: Unit.cpp:5048
void UnsummonAllTotems(bool onDeath=false)
Definition: Unit.cpp:11153
void RemoveAllDynObjects()
Definition: Unit.cpp:6063
void RemoveAreaAurasDueToLeaveWorld()
Definition: Unit.cpp:5194
void RemoveBindSightAuras()
Definition: Unit.cpp:11140
void RemoveAllControlled(bool onDeath=false)
Definition: Unit.cpp:11034
void RemoveFromWorld() override
Definition: Object.cpp:1182

◆ RemoveGameObject() [1/2]

void Unit::RemoveGameObject ( GameObject gameObj,
bool  del 
)
6098{
6099 if (!gameObj || gameObj->GetOwnerGUID() != GetGUID())
6100 return;
6101
6103
6104 for (uint8 i = 0; i < MAX_GAMEOBJECT_SLOT; ++i)
6105 {
6106 if (m_ObjectSlot[i] == gameObj->GetGUID())
6107 {
6108 m_ObjectSlot[i].Clear();
6109 break;
6110 }
6111 }
6112
6113 // GO created by some spell
6114 if (uint32 spellid = gameObj->GetSpellId())
6115 {
6116 RemoveAurasDueToSpell(spellid);
6117
6118 if (GetTypeId() == TYPEID_PLAYER)
6119 {
6120 SpellInfo const* createBySpell = sSpellMgr->GetSpellInfo(spellid);
6121 // Need activate spell use for owner
6122 if (createBySpell && createBySpell->IsCooldownStartedOnEvent())
6123 // note: item based cooldowns and cooldown spell mods with charges ignored (unknown existing cases)
6124 ToPlayer()->SendCooldownEvent(createBySpell);
6125 }
6126 }
6127
6128 m_gameObj.remove(gameObj->GetGUID());
6129
6130 if (del)
6131 {
6132 gameObj->SetRespawnTime(0);
6133 gameObj->Delete();
6134 }
6135}
void Clear()
Definition: ObjectGuid.h:140
void SendCooldownEvent(SpellInfo const *spellInfo, uint32 itemId=0, Spell *spell=nullptr, bool setCooldown=true)
Definition: Player.cpp:10848

◆ RemoveGameObject() [2/2]

void Unit::RemoveGameObject ( uint32  spellid,
bool  del 
)
6138{
6139 if (m_gameObj.empty())
6140 return;
6141
6142 for (GameObjectList::iterator itr = m_gameObj.begin(); itr != m_gameObj.end();)
6143 {
6144 if (GameObject* go = ObjectAccessor::GetGameObject(*this, *itr))
6145 {
6146 if (spellid > 0 && go->GetSpellId() != spellid)
6147 {
6148 ++itr;
6149 continue;
6150 }
6151
6152 go->SetOwnerGUID(ObjectGuid::Empty);
6153 if(del)
6154 {
6155 go->SetRespawnTime(0);
6156 go->Delete();
6157 }
6158 }
6159 m_gameObj.erase(itr++);
6160 }
6161}

◆ removeHatedBy()

void Unit::removeHatedBy ( HostileReference )
inline
2145{ /* nothing to do yet */ }

◆ RemoveMovementImpairingAuras()

void Unit::RemoveMovementImpairingAuras ( bool  withRoot)
5138{
5139 if (withRoot)
5141
5142 // Snares
5143 for (AuraApplicationMap::iterator iter = m_appliedAuras.begin(); iter != m_appliedAuras.end();)
5144 {
5145 Aura const* aura = iter->second->GetBase();
5146 if (aura->GetSpellInfo()->Mechanic == MECHANIC_SNARE)
5147 {
5148 RemoveAura(iter);
5149 continue;
5150 }
5151
5152 // Xinef: turn off snare auras by setting amount to 0 :)
5153 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
5154 if (((1 << i) & iter->second->GetEffectMask()) && aura->GetSpellInfo()->Effects[i].Mechanic == MECHANIC_SNARE)
5155 aura->GetEffect(i)->ChangeAmount(0);
5156
5157 ++iter;
5158 }
5159}
void ChangeAmount(int32 newAmount, bool mark=true, bool onStackOrReapply=false)
Definition: SpellAuraEffects.cpp:702

◆ RemoveNotOwnSingleTargetAuras()

void Unit::RemoveNotOwnSingleTargetAuras ( )
5049{
5050 // single target auras from other casters
5051 // Iterate m_ownedAuras - aura is marked as single target in Unit::AddAura (and pushed to m_ownedAuras).
5052 // m_appliedAuras will NOT contain the aura before first Unit::Update after adding it to m_ownedAuras.
5053 // Quickly removing such an aura will lead to it not being unregistered from caster's single cast auras container
5054 // leading to assertion failures if the aura was cast on a player that can
5055 // (and is changing map at the point where this function is called).
5056 // Such situation occurs when player is logging in inside an instance and fails the entry check for any reason.
5057 // The aura that was loaded from db (indirectly, via linked casts) gets removed before it has a chance
5058 // to register in m_appliedAuras
5059 for (AuraMap::iterator iter = m_ownedAuras.begin(); iter != m_ownedAuras.end();)
5060 {
5061 Aura const* aura = iter->second;
5062
5063 if (aura->GetCasterGUID() != GetGUID() && aura->IsSingleTarget())
5064 RemoveOwnedAura(iter);
5065 else
5066 ++iter;
5067 }
5068
5069 // single target auras at other targets
5070 AuraList& scAuras = GetSingleCastAuras();
5071 for (AuraList::iterator iter = scAuras.begin(); iter != scAuras.end();)
5072 {
5073 Aura* aura = *iter;
5074 if (aura->GetUnitOwner() != this)
5075 {
5076 aura->Remove();
5077 iter = scAuras.begin();
5078 }
5079 else
5080 ++iter;
5081 }
5082}

◆ RemoveNpcFlag()

void Unit::RemoveNpcFlag ( NPCFlags  flags)
inline
1645{ RemoveFlag(UNIT_NPC_FLAGS, flags); }

◆ RemoveOwnedAura() [1/3]

void Unit::RemoveOwnedAura ( Aura aura,
AuraRemoveMode  removeMode = AURA_REMOVE_BY_DEFAULT 
)
4659{
4660 if (aura->IsRemoved())
4661 return;
4662
4663 ASSERT(aura->GetOwner() == this);
4664
4665 uint32 spellId = aura->GetId();
4666 AuraMapBoundsNonConst range = m_ownedAuras.equal_range(spellId);
4667
4668 for (AuraMap::iterator itr = range.first; itr != range.second; ++itr)
4669 {
4670 if (itr->second == aura)
4671 {
4672 RemoveOwnedAura(itr, removeMode);
4673 return;
4674 }
4675 }
4676
4677 ABORT();
4678}

◆ RemoveOwnedAura() [2/3]

void Unit::RemoveOwnedAura ( AuraMap::iterator &  i,
AuraRemoveMode  removeMode = AURA_REMOVE_BY_DEFAULT 
)
4626{
4627 Aura* aura = i->second;
4628 ASSERT(!aura->IsRemoved());
4629
4630 // if unit currently update aura list then make safe update iterator shift to next
4633
4634 m_ownedAuras.erase(i);
4635 m_removedAuras.push_back(aura);
4636
4637 // Unregister single target aura
4638 if (aura->IsSingleTarget())
4639 aura->UnregisterSingleTarget();
4640
4641 aura->_Remove(removeMode);
4642
4643 i = m_ownedAuras.begin();
4644}
void _Remove(AuraRemoveMode removeMode)
Definition: SpellAuras.cpp:574

◆ RemoveOwnedAura() [3/3]

void Unit::RemoveOwnedAura ( uint32  spellId,
ObjectGuid  casterGUID = ObjectGuid::Empty,
uint8  reqEffMask = 0,
AuraRemoveMode  removeMode = AURA_REMOVE_BY_DEFAULT 
)
4647{
4648 for (AuraMap::iterator itr = m_ownedAuras.lower_bound(spellId); itr != m_ownedAuras.upper_bound(spellId);)
4649 if (((itr->second->GetEffectMask() & reqEffMask) == reqEffMask) && (!casterGUID || itr->second->GetCasterGUID() == casterGUID))
4650 {
4651 RemoveOwnedAura(itr, removeMode);
4652 itr = m_ownedAuras.lower_bound(spellId);
4653 }
4654 else
4655 ++itr;
4656}

◆ RemoveOwnedAuras() [1/2]

void Unit::RemoveOwnedAuras ( std::function< bool(Aura const *)> const &  check)
4772{
4773 for (AuraMap::iterator iter = m_ownedAuras.begin(); iter != m_ownedAuras.end();)
4774 {
4775 if (check(iter->second))
4776 {
4777 RemoveOwnedAura(iter);
4778 continue;
4779 }
4780 ++iter;
4781 }
4782}

◆ RemoveOwnedAuras() [2/2]

void Unit::RemoveOwnedAuras ( uint32  spellId,
std::function< bool(Aura const *)> const &  check 
)
4798{
4799 for (AuraMap::iterator iter = m_ownedAuras.lower_bound(spellId); iter != m_ownedAuras.upper_bound(spellId);)
4800 {
4801 if (check(iter->second))
4802 {
4803 RemoveOwnedAura(iter);
4804 continue;
4805 }
4806 ++iter;
4807 }
4808}

◆ RemovePetAura()

void Unit::RemovePetAura ( PetAura const *  petSpell)
17360{
17361 if (GetTypeId() != TYPEID_PLAYER)
17362 return;
17363
17364 m_petAuras.erase(petSpell);
17365 if (Pet* pet = ToPlayer()->GetPet())
17366 pet->RemoveAurasDueToSpell(petSpell->GetAura(pet->GetEntry()));
17367 if (Unit* charm = GetCharm())
17368 charm->RemoveAurasDueToSpell(petSpell->GetAura(charm->GetEntry()));
17369}

◆ RemovePlayerFromVision()

void Unit::RemovePlayerFromVision ( Player player)
11130{
11131 m_sharedVision.remove(player);
11132 player->m_isInSharedVisionOf.erase(this);
11133 if (m_sharedVision.empty())
11134 {
11135 setActive(false);
11136 SetWorldObject(false);
11137 }
11138}

◆ RemovePointedBy()

void Unit::RemovePointedBy ( SafeUnitPointer sup)
inline
2401{ SafeUnitPointerSet.erase(sup); }

◆ RemoveStandFlags()

void Unit::RemoveStandFlags ( uint8  flags)
inline
@ UNIT_BYTES_1_OFFSET_VIS_FLAG
Definition: Unit.h:46
void RemoveByteFlag(uint16 index, uint8 offset, uint8 newFlag)
Definition: Object.cpp:930

◆ RemoveUnitFlag()

void Unit::RemoveUnitFlag ( UnitFlags  flags)
inline
1480{ RemoveFlag(UNIT_FIELD_FLAGS, flags); }

◆ RemoveUnitFlag2()

void Unit::RemoveUnitFlag2 ( UnitFlags2  flags)
inline
1486{ RemoveFlag(UNIT_FIELD_FLAGS_2, flags); }

◆ RemoveUnitMovementFlag()

void Unit::RemoveUnitMovementFlag ( uint32  f)
inline
2268{ m_movementInfo.flags &= ~f; }

◆ RemoveVehicleKit()

void Unit::RemoveVehicleKit ( )
18760{
18761 if (!m_vehicleKit)
18762 return;
18763
18765 delete m_vehicleKit;
18766
18767 m_vehicleKit = nullptr;
18768
18769 m_updateFlag &= ~UPDATEFLAG_VEHICLE;
18770 m_unitTypeMask &= ~UNIT_MASK_VEHICLE;
18772}
@ UNIT_NPC_FLAG_SPELLCLICK
Definition: Unit.h:540
@ UNIT_NPC_FLAG_PLAYER_VEHICLE
Definition: Unit.h:541
void RemoveNpcFlag(NPCFlags flags)
Definition: Unit.h:1645

◆ RemoveVisibleAura()

void Unit::RemoveVisibleAura ( uint8  slot)
inline
2157{ m_visibleAuras.erase(slot); UpdateAuraForGroup(slot);}
void UpdateAuraForGroup(uint8 slot)
Definition: Unit.cpp:17230

◆ ReplaceAllDynamicFlags()

void Unit::ReplaceAllDynamicFlags ( uint32  flag)
inlineoverridevirtual

Reimplemented from Object.

◆ ReplaceAllNpcFlags()

void Unit::ReplaceAllNpcFlags ( NPCFlags  flags)
inline
1646{ SetUInt32Value(UNIT_NPC_FLAGS, flags); }

◆ ReplaceAllUnitFlags()

void Unit::ReplaceAllUnitFlags ( UnitFlags  flags)
inline

◆ ReplaceAllUnitFlags2()

void Unit::ReplaceAllUnitFlags2 ( UnitFlags2  flags)
inline

◆ resetAttackTimer()

void Unit::resetAttackTimer ( WeaponAttackType  type = BASE_ATTACK)
661{
662 int32 time = int32(GetAttackTime(type) * m_modAttackSpeedPct[type]);
663 m_attackTimer[type] = std::min(m_attackTimer[type] + time, time);
664}

◆ ResetRedirectThreat()

void Unit::ResetRedirectThreat ( )
inline
void SetRedirectThreat(ObjectGuid guid, uint32 pct)
Definition: Unit.h:2339

◆ RestoreDisplayId()

void Unit::RestoreDisplayId ( )
16851{
16852 AuraEffect* handledAura = nullptr;
16853 AuraEffect* handledAuraForced = nullptr;
16854 // try to receive model from transform auras
16856 if (!transforms.empty())
16857 {
16858 // iterate over already applied transform auras - from newest to oldest
16859 for (Unit::AuraEffectList::const_reverse_iterator i = transforms.rbegin(); i != transforms.rend(); ++i)
16860 {
16861 if (AuraApplication const* aurApp = (*i)->GetBase()->GetApplicationOfTarget(GetGUID()))
16862 {
16863 if (!handledAura)
16864 handledAura = (*i);
16865 // xinef: prefer negative/forced auras
16866 if ((*i)->GetSpellInfo()->HasAttribute(SPELL_ATTR0_NO_IMMUNITIES) || !aurApp->IsPositive())
16867 {
16868 handledAuraForced = (*i);
16869 break;
16870 }
16871 }
16872 }
16873 }
16874
16875 // Xinef: include clone auras (eg mirror images)
16876 if (!handledAuraForced && !handledAura)
16877 {
16879 if (!cloneAuras.empty())
16880 for (Unit::AuraEffectList::const_iterator i = cloneAuras.begin(); i != cloneAuras.end(); ++i)
16881 handledAura = *i;
16882 }
16883
16884 // xinef: order of execution is important!
16885 // first forced transform auras, then shapeshifts, then normal transform
16886 // transform aura was found
16887 if (handledAuraForced)
16888 handledAuraForced->HandleEffect(this, AURA_EFFECT_HANDLE_SEND_FOR_CLIENT, true);
16889 // we've found shapeshift
16890 else if (uint32 modelId = GetModelForForm(GetShapeshiftForm()))
16891 SetDisplayId(modelId);
16892 else if (handledAura)
16893 handledAura->HandleEffect(this, AURA_EFFECT_HANDLE_SEND_FOR_CLIENT, true);
16894 // no auras found - set modelid to default
16895 else
16897}
@ AURA_EFFECT_HANDLE_SEND_FOR_CLIENT
Definition: SpellAuraDefines.h:43
void HandleEffect(AuraApplication *aurApp, uint8 mode, bool apply)
Definition: SpellAuraEffects.cpp:735
uint32 GetModelForForm(ShapeshiftForm form) const
Definition: Unit.cpp:19233

◆ RestoreFaction()

void Unit::RestoreFaction ( )
18728{
18729 if (GetTypeId() == TYPEID_PLAYER)
18731 else
18732 {
18734 {
18735 if (Unit* owner = GetOwner())
18736 {
18737 SetFaction(owner->GetFaction());
18738 return;
18739 }
18740 }
18741
18742 if (CreatureTemplate const* cinfo = ToCreature()->GetCreatureTemplate()) // normal creature
18743 SetFaction(cinfo->faction);
18744 }
18745}
void SetFactionForRace(uint8 race)
Definition: Player.cpp:5734

◆ ResumeMovement()

void Unit::ResumeMovement ( uint32  timer = 0,
uint8  slot = 0 
)
16767{
16768 if (slot >= MAX_MOTION_SLOT)
16769 return;
16770
16771 if (MovementGenerator* movementGenerator = GetMotionMaster()->GetMotionSlot(slot))
16772 movementGenerator->Resume(timer);
16773}

◆ RewardRage()

void Unit::RewardRage ( uint32  damage,
uint32  weaponSpeedHitFactor,
bool  attacker 
)
20143{
20144 float addRage;
20145
20146 float rageconversion = ((0.0091107836f * getLevel() * getLevel()) + 3.225598133f * getLevel()) + 4.2652911f;
20147
20148 // Unknown if correct, but lineary adjust rage conversion above level 70
20149 if (getLevel() > 70)
20150 rageconversion += 13.27f * (getLevel() - 70);
20151
20152 if (attacker)
20153 {
20154 addRage = (damage / rageconversion * 7.5f + weaponSpeedHitFactor) / 2;
20155
20156 // talent who gave more rage on attack
20158 }
20159 else
20160 {
20161 addRage = damage / rageconversion * 2.5f;
20162
20163 // Berserker Rage effect
20164 if (HasAura(18499))
20165 addRage *= 3.0f;
20166 }
20167
20168 addRage *= sWorld->getRate(RATE_POWER_RAGE_INCOME);
20169
20170 ModifyPower(POWER_RAGE, uint32(addRage * 10));
20171}
@ RATE_POWER_RAGE_INCOME
Definition: IWorld.h:418
@ SPELL_AURA_MOD_RAGE_FROM_DAMAGE_DEALT
Definition: SpellAuraDefines.h:276

◆ RollMeleeOutcomeAgainst() [1/2]

MeleeHitOutcome Unit::RollMeleeOutcomeAgainst ( Unit const *  victim,
WeaponAttackType  attType 
) const
2732{
2733 // This is only wrapper
2734
2735 // Miss chance based on melee
2736 //float miss_chance = MeleeMissChanceCalc(victim, attType);
2737 float miss_chance = MeleeSpellMissChance(victim, attType, int32(GetWeaponSkillValue(attType, victim)) - int32(victim->GetMaxSkillValueForLevel(this)), 0);
2738
2739 // Critical hit chance
2740 float crit_chance = GetUnitCriticalChance(attType, victim);
2741 if( crit_chance < 0 )
2742 crit_chance = 0;
2743
2744 float dodge_chance = victim->GetUnitDodgeChance();
2745 float block_chance = victim->GetUnitBlockChance();
2746 float parry_chance = victim->GetUnitParryChance();
2747
2748 // Useful if want to specify crit & miss chances for melee, else it could be removed
2749 //LOG_DEBUG("entities.unit", "MELEE OUTCOME: miss {} crit {} dodge {} parry {} block {}", miss_chance, crit_chance, dodge_chance, parry_chance, block_chance);
2750
2751 return RollMeleeOutcomeAgainst(victim, attType, int32(crit_chance * 100), int32(miss_chance * 100), int32(dodge_chance * 100), int32(parry_chance * 100), int32(block_chance * 100));
2752}
float GetUnitCriticalChance(WeaponAttackType attackType, Unit const *victim) const
Definition: Unit.cpp:3669

◆ RollMeleeOutcomeAgainst() [2/2]

MeleeHitOutcome Unit::RollMeleeOutcomeAgainst ( Unit const *  victim,
WeaponAttackType  attType,
int32  crit_chance,
int32  miss_chance,
int32  dodge_chance,
int32  parry_chance,
int32  block_chance 
) const
2755{
2756 if (victim->GetTypeId() == TYPEID_UNIT && victim->ToCreature()->IsEvadingAttacks())
2757 {
2758 return MELEE_HIT_EVADE;
2759 }
2760
2761 int32 attackerMaxSkillValueForLevel = GetMaxSkillValueForLevel(victim);
2762 int32 victimMaxSkillValueForLevel = victim->GetMaxSkillValueForLevel(this);
2763
2764 int32 attackerWeaponSkill = GetWeaponSkillValue(attType, victim);
2765 int32 victimDefenseSkill = victim->GetDefenseSkillValue(this);
2766
2767 sScriptMgr->OnBeforeRollMeleeOutcomeAgainst(this, victim, attType, attackerMaxSkillValueForLevel, victimMaxSkillValueForLevel, attackerWeaponSkill, victimDefenseSkill, crit_chance, miss_chance, dodge_chance, parry_chance, block_chance);
2768
2769 // bonus from skills is 0.04%
2770 int32 skillBonus = 4 * (attackerWeaponSkill - victimMaxSkillValueForLevel);
2771 int32 sum = 0, tmp = 0;
2772 int32 roll = urand (0, 10000);
2773
2774 LOG_DEBUG("entities.unit", "RollMeleeOutcomeAgainst: skill bonus of {} for attacker", skillBonus);
2775 //LOG_DEBUG("entities.unit", "RollMeleeOutcomeAgainst: rolled {}, miss {}, dodge {}, parry {}, block {}, crit {}",
2776 // roll, miss_chance, dodge_chance, parry_chance, block_chance, crit_chance);
2777
2778 tmp = miss_chance;
2779
2780 if (tmp > 0 && roll < (sum += tmp))
2781 {
2782 LOG_DEBUG("entities.unit", "RollMeleeOutcomeAgainst: MISS");
2783 return MELEE_HIT_MISS;
2784 }
2785
2786 // Dodge chance
2787
2788 // only players can't dodge if attacker is behind
2789 if (victim->GetTypeId() == TYPEID_PLAYER && !victim->HasInArc(M_PI, this) && !victim->HasAuraType(SPELL_AURA_IGNORE_HIT_DIRECTION))
2790 {
2791 //LOG_DEBUG("entities.unit", "RollMeleeOutcomeAgainst: attack came from behind and victim was a player.");
2792 }
2793 // Xinef: do not allow to dodge with CREATURE_FLAG_EXTRA_NO_DODGE flag
2794 else if (victim->GetTypeId() == TYPEID_PLAYER || !(victim->ToCreature()->GetCreatureTemplate()->flags_extra & CREATURE_FLAG_EXTRA_NO_DODGE))
2795 {
2796 // Reduce dodge chance by attacker expertise rating
2797 if (GetTypeId() == TYPEID_PLAYER)
2798 dodge_chance -= int32(ToPlayer()->GetExpertiseDodgeOrParryReduction(attType) * 100);
2799 else
2800 dodge_chance -= GetTotalAuraModifier(SPELL_AURA_MOD_EXPERTISE) * 25;
2801
2802 // Modify dodge chance by attacker SPELL_AURA_MOD_COMBAT_RESULT_CHANCE
2804 dodge_chance = int32 (float (dodge_chance) * GetTotalAuraMultiplier(SPELL_AURA_MOD_ENEMY_DODGE));
2805
2806 tmp = dodge_chance;
2807
2808 // xinef: if casting or stunned - cant dodge
2809 if (victim->IsNonMeleeSpellCast(false, false, true) || victim->HasUnitState(UNIT_STATE_CONTROLLED))
2810 tmp = 0;
2811
2812 if ((tmp > 0) // check if unit _can_ dodge
2813 && ((tmp -= skillBonus) > 0)
2814 && roll < (sum += tmp))
2815 {
2816 LOG_DEBUG("entities.unit", "RollMeleeOutcomeAgainst: DODGE <{}, {})", sum - tmp, sum);
2817 return MELEE_HIT_DODGE;
2818 }
2819 }
2820
2821 // parry & block chances
2822
2823 // check if attack comes from behind, nobody can parry or block if attacker is behind
2824 if (!victim->HasInArc(M_PI, this) && !victim->HasAuraType(SPELL_AURA_IGNORE_HIT_DIRECTION))
2825 {
2826 LOG_DEBUG("entities.unit", "RollMeleeOutcomeAgainst: attack came from behind.");
2827 }
2828 else
2829 {
2830 // Reduce parry chance by attacker expertise rating
2831 if (GetTypeId() == TYPEID_PLAYER)
2832 parry_chance -= int32(ToPlayer()->GetExpertiseDodgeOrParryReduction(attType) * 100);
2833 else
2834 parry_chance -= GetTotalAuraModifier(SPELL_AURA_MOD_EXPERTISE) * 25;
2835
2836 if (victim->GetTypeId() == TYPEID_PLAYER || !(victim->ToCreature()->GetCreatureTemplate()->flags_extra & CREATURE_FLAG_EXTRA_NO_PARRY))
2837 {
2838 tmp = parry_chance;
2839
2840 // xinef: cant parry while casting or while stunned
2841 if (victim->IsNonMeleeSpellCast(false, false, true) || victim->HasUnitState(UNIT_STATE_CONTROLLED))
2842 tmp = 0;
2843
2844 if (tmp > 0 // check if unit _can_ parry
2845 && (tmp -= skillBonus) > 0
2846 && roll < (sum += tmp))
2847 {
2848 LOG_DEBUG("entities.unit", "RollMeleeOutcomeAgainst: PARRY <{}, {})", sum - tmp, sum);
2849 return MELEE_HIT_PARRY;
2850 }
2851 }
2852
2853 if (victim->GetTypeId() == TYPEID_PLAYER || !(victim->ToCreature()->GetCreatureTemplate()->flags_extra & CREATURE_FLAG_EXTRA_NO_BLOCK))
2854 {
2855 tmp = block_chance;
2856
2857 // xinef: cant block while casting or while stunned
2858 if (victim->IsNonMeleeSpellCast(false, false, true) || victim->HasUnitState(UNIT_STATE_CONTROLLED))
2859 tmp = 0;
2860
2861 if (tmp > 0 // check if unit _can_ block
2862 && (tmp -= skillBonus) > 0
2863 && roll < (sum += tmp))
2864 {
2865 LOG_DEBUG("entities.unit", "RollMeleeOutcomeAgainst: BLOCK <{}, {})", sum - tmp, sum);
2866 return MELEE_HIT_BLOCK;
2867 }
2868 }
2869 }
2870
2871 // Max 40% chance to score a glancing blow against mobs that are higher level (can do only players and pets and not with ranged weapon)
2872 if (attType != RANGED_ATTACK &&
2873 (GetTypeId() == TYPEID_PLAYER || IsPet()) &&
2874 victim->GetTypeId() != TYPEID_PLAYER && !victim->IsPet() &&
2875 getLevel() < victim->getLevelForTarget(this))
2876 {
2877 // cap possible value (with bonuses > max skill)
2878 int32 skill = attackerWeaponSkill;
2879 int32 maxskill = attackerMaxSkillValueForLevel;
2880 skill = (skill > maxskill) ? maxskill : skill;
2881
2882 tmp = (10 + (victimDefenseSkill - skill)) * 100;
2883 tmp = tmp > 4000 ? 4000 : tmp;
2884 if (roll < (sum += tmp))
2885 {
2886 LOG_DEBUG("entities.unit", "RollMeleeOutcomeAgainst: GLANCING <{}, {})", sum - 4000, sum);
2887 return MELEE_HIT_GLANCING;
2888 }
2889 }
2890
2891 // mobs can score crushing blows if they're 4 or more levels above victim
2892 if (getLevelForTarget(victim) >= victim->getLevelForTarget(this) + 4 &&
2893 // can be from by creature (if can) or from controlled player that considered as creature
2895 !(GetTypeId() == TYPEID_UNIT && ToCreature()->GetCreatureTemplate()->flags_extra & CREATURE_FLAG_EXTRA_NO_CRUSHING_BLOWS))
2896 {
2897 // when their weapon skill is 15 or more above victim's defense skill
2898 tmp = victimDefenseSkill;
2899 int32 tmpmax = victimMaxSkillValueForLevel;
2900 // having defense above your maximum (from items, talents etc.) has no effect
2901 tmp = tmp > tmpmax ? tmpmax : tmp;
2902 // tmp = mob's level * 5 - player's current defense skill
2903 tmp = attackerMaxSkillValueForLevel - tmp;
2904 if (tmp >= 15)
2905 {
2906 // add 2% chance per lacking skill point, min. is 15%
2907 tmp = tmp * 200 - 1500;
2908 if (roll < (sum += tmp))
2909 {
2910 LOG_DEBUG("entities.unit", "RollMeleeOutcomeAgainst: CRUSHING <{}, {})", sum - tmp, sum);
2911 return MELEE_HIT_CRUSHING;
2912 }
2913 }
2914 }
2915
2916 // Critical chance
2917 tmp = crit_chance;
2918
2919 if (tmp > 0 && roll < (sum += tmp))
2920 {
2921 LOG_DEBUG("entities.unit", "RollMeleeOutcomeAgainst: CRIT <{}, {})", sum - tmp, sum);
2922 if (GetTypeId() == TYPEID_UNIT && (ToCreature()->GetCreatureTemplate()->flags_extra & CREATURE_FLAG_EXTRA_NO_CRIT))
2923 {
2924 LOG_DEBUG("entities.unit", "RollMeleeOutcomeAgainst: CRIT DISABLED)");
2925 }
2926 else
2927 return MELEE_HIT_CRIT;
2928 }
2929
2930 LOG_DEBUG("entities.unit", "RollMeleeOutcomeAgainst: NORMAL");
2931 return MELEE_HIT_NORMAL;
2932}
@ CREATURE_FLAG_EXTRA_NO_CRUSHING_BLOWS
Definition: CreatureData.h:54
@ CREATURE_FLAG_EXTRA_NO_CRIT
Definition: CreatureData.h:66

◆ Say() [1/2]

void Unit::Say ( std::string_view  text,
Language  language,
WorldObject const *  target = nullptr 
)
virtual

Reimplemented in Player.

21144{
21145 Talk(text, CHAT_MSG_MONSTER_SAY, language, sWorld->getFloatConfig(CONFIG_LISTEN_RANGE_SAY), target);
21146}
@ CONFIG_LISTEN_RANGE_SAY
Definition: IWorld.h:188
@ CHAT_MSG_MONSTER_SAY
Definition: SharedDefines.h:3136
Talk
Definition: boss_fathomlord_karathress.cpp:23

◆ Say() [2/2]

void Unit::Say ( uint32  textId,
WorldObject const *  target = nullptr 
)
virtual

Reimplemented in Player.

21186{
21187 Talk(textId, CHAT_MSG_MONSTER_SAY, sWorld->getFloatConfig(CONFIG_LISTEN_RANGE_SAY), target);
21188}

◆ SelectNearbyNoTotemTarget()

Unit * Unit::SelectNearbyNoTotemTarget ( Unit exclude = nullptr,
float  dist = NOMINAL_MELEE_RANGE 
) const
17081{
17082 std::list<Unit*> targets;
17083 Acore::AnyUnfriendlyNoTotemUnitInObjectRangeCheck u_check(this, this, dist);
17085 Cell::VisitAllObjects(this, searcher, dist);
17086
17087 // remove current target
17088 if (GetVictim())
17089 targets.remove(GetVictim());
17090
17091 if (exclude)
17092 targets.remove(exclude);
17093
17094 // remove not LoS targets
17095 for (std::list<Unit*>::iterator tIter = targets.begin(); tIter != targets.end();)
17096 {
17097 if (!IsWithinLOSInMap(*tIter) || !IsValidAttackTarget(*tIter))
17098 {
17099 std::list<Unit*>::iterator tIter2 = tIter;
17100 ++tIter;
17101 targets.erase(tIter2);
17102 }
17103 else
17104 ++tIter;
17105 }
17106
17107 // no appropriate targets
17108 if (targets.empty())
17109 return nullptr;
17110
17111 // select random
17113}
bool IsValidAttackTarget(Unit const *target) const
Definition: Unit.cpp:13764
auto SelectRandomContainerElement(C const &container) -> typename std::add_const< decltype(*std::begin(container))>::type &
Definition: Containers.h:135
Definition: GridNotifiers.h:420

◆ SelectNearbyTarget()

Unit * Unit::SelectNearbyTarget ( Unit exclude = nullptr,
float  dist = NOMINAL_MELEE_RANGE 
) const
17046{
17047 std::list<Unit*> targets;
17048 Acore::AnyUnfriendlyUnitInObjectRangeCheck u_check(this, this, dist);
17050 Cell::VisitAllObjects(this, searcher, dist);
17051
17052 // remove current target
17053 if (GetVictim())
17054 targets.remove(GetVictim());
17055
17056 if (exclude)
17057 targets.remove(exclude);
17058
17059 // remove not LoS targets
17060 for (std::list<Unit*>::iterator tIter = targets.begin(); tIter != targets.end();)
17061 {
17062 if (!IsWithinLOSInMap(*tIter) || !IsValidAttackTarget(*tIter))
17063 {
17064 std::list<Unit*>::iterator tIter2 = tIter;
17065 ++tIter;
17066 targets.erase(tIter2);
17067 }
17068 else
17069 ++tIter;
17070 }
17071
17072 // no appropriate targets
17073 if (targets.empty())
17074 return nullptr;
17075
17076 // select random
17078}
Definition: GridNotifiers.h:858

◆ SendAttackStateUpdate() [1/2]

void Unit::SendAttackStateUpdate ( CalcDamageInfo damageInfo)

Probably used for debugging purposes, as it is not known to appear on retail servers

6380{
6381 LOG_DEBUG("entities.unit", "WORLD: Sending SMSG_ATTACKERSTATEUPDATE");
6382
6383 uint32 tmpDamage[MAX_ITEM_PROTO_DAMAGES] = { };
6384 uint32 tmpAbsorb[MAX_ITEM_PROTO_DAMAGES] = { };
6385 for (uint8 i = 0; i < MAX_ITEM_PROTO_DAMAGES; ++i)
6386 {
6387 //IF we are in cheat mode we swap absorb with damage and set damage to 0, this way we can still debug damage but our hp bar will not drop
6388 tmpDamage[i] = damageInfo->damages[i].damage;
6389 tmpAbsorb[i] = damageInfo->damages[i].absorb;
6390 if (damageInfo->target->GetTypeId() == TYPEID_PLAYER && damageInfo->target->ToPlayer()->GetCommandStatus(CHEAT_GOD))
6391 {
6392 tmpAbsorb[i] = tmpDamage[i];
6393 tmpDamage[i] = 0;
6394 }
6395 }
6396
6397 uint32 count = 1;
6398 if (tmpDamage[1] || tmpAbsorb[1] || damageInfo->damages[1].resist)
6399 {
6400 ++count;
6401 }
6402
6403 size_t const maxsize = 4 + 5 + 5 + 4 + 4 + 1 + count * (4 + 4 + 4 + 4 + 4) + 1 + 4 + 4 + 4 + 4 + 4 * 12;
6404 WorldPacket data(SMSG_ATTACKERSTATEUPDATE, maxsize); // we guess size
6405 data << uint32(damageInfo->HitInfo);
6406 data << damageInfo->attacker->GetPackGUID();
6407 data << damageInfo->target->GetPackGUID();
6408 data << uint32(tmpDamage[0] + tmpDamage[1]); // Full damage
6409 int32 overkill = tmpDamage[0] + tmpDamage[1] - damageInfo->target->GetHealth();
6410 data << uint32(overkill < 0 ? 0 : overkill); // Overkill
6411 data << uint8(count); // Sub damage count
6412
6413 for (uint32 i = 0; i < count; ++i)
6414 {
6415 data << uint32(damageInfo->damages[i].damageSchoolMask); // School of sub damage
6416 data << float(tmpDamage[i]); // sub damage
6417 data << uint32(tmpDamage[i]); // Sub Damage
6418 }
6419
6421 {
6422 for (uint32 i = 0; i < count; ++i)
6423 {
6424 data << uint32(tmpAbsorb[i]); // Absorb
6425 }
6426 }
6427
6429 {
6430 for (uint32 i = 0; i < count; ++i)
6431 {
6432 data << uint32(damageInfo->damages[i].resist); // Resist
6433 }
6434 }
6435
6436 data << uint8(damageInfo->TargetState);
6437 data << uint32(0); // Unknown attackerstate
6438 data << uint32(0); // Melee spellid
6439
6440 if (damageInfo->HitInfo & HITINFO_BLOCK)
6441 data << uint32(damageInfo->blocked_amount);
6442
6443 if (damageInfo->HitInfo & HITINFO_RAGE_GAIN)
6444 data << uint32(0);
6445
6447 if (damageInfo->HitInfo & HITINFO_UNK1)
6448 {
6449 data << uint32(0);
6450 data << float(0);
6451 data << float(0);
6452 data << float(0);
6453 data << float(0);
6454 data << float(0);
6455 data << float(0);
6456 data << float(0);
6457 data << float(0);
6458 data << float(0); // Found in a loop with 1 iteration
6459 data << float(0); // ditto ^
6460 data << uint32(0);
6461 }
6462
6463 SendMessageToSet(&data, true);
6464}
@ HITINFO_RAGE_GAIN
Definition: Unit.h:203
@ HITINFO_UNK1
Definition: Unit.h:180
@ SMSG_ATTACKERSTATEUPDATE
Definition: Opcodes.h:360

◆ SendAttackStateUpdate() [2/2]

void Unit::SendAttackStateUpdate ( uint32  HitInfo,
Unit target,
uint8  SwingType,
SpellSchoolMask  damageSchoolMask,
uint32  Damage,
uint32  AbsorbDamage,
uint32  Resist,
VictimState  TargetState,
uint32  BlockedAmount 
)
6467{
6468 CalcDamageInfo dmgInfo;
6469 dmgInfo.HitInfo = HitInfo;
6470 dmgInfo.attacker = this;
6471 dmgInfo.target = target;
6472
6473 dmgInfo.damages[0].damage = Damage - AbsorbDamage - Resist - BlockedAmount;
6474 dmgInfo.damages[0].damageSchoolMask = damageSchoolMask;
6475 dmgInfo.damages[0].absorb = AbsorbDamage;
6476 dmgInfo.damages[0].resist = Resist;
6477
6478 dmgInfo.damages[1].damage = 0;
6479 dmgInfo.damages[1].damageSchoolMask = 0;
6480 dmgInfo.damages[1].absorb = 0;
6481 dmgInfo.damages[1].resist = 0;
6482
6483 dmgInfo.TargetState = TargetState;
6484 dmgInfo.blocked_amount = BlockedAmount;
6485 SendAttackStateUpdate(&dmgInfo);
6486}
HitInfo
Definition: Unit.h:178

◆ SendChangeCurrentVictimOpcode()

void Unit::SendChangeCurrentVictimOpcode ( HostileReference pHostileReference)
20105{
20106 if (!GetThreatMgr().isThreatListEmpty())
20107 {
20108 uint32 count = GetThreatMgr().GetThreatList().size();
20109
20110 LOG_DEBUG("entities.unit", "WORLD: Send SMSG_HIGHEST_THREAT_UPDATE Message");
20111 WorldPacket data(SMSG_HIGHEST_THREAT_UPDATE, 8 + 8 + count * 8);
20112 data << GetPackGUID();
20113 data << pHostileReference->getUnitGuid().WriteAsPacked();
20114 data << uint32(count);
20116 for (ThreatContainer::StorageType::const_iterator itr = tlist.begin(); itr != tlist.end(); ++itr)
20117 {
20118 data << (*itr)->getUnitGuid().WriteAsPacked();
20119 data << uint32((*itr)->GetThreat() * 100);
20120 }
20121 SendMessageToSet(&data, false);
20122 }
20123}
PackedGuid WriteAsPacked() const
Definition: ObjectGuid.h:318
std::list< HostileReference * > StorageType
Definition: ThreatMgr.h:148
@ SMSG_HIGHEST_THREAT_UPDATE
Definition: Opcodes.h:1184

◆ SendClearTarget()

void Unit::SendClearTarget ( )
20317{
20319 data << GetPackGUID();
20320 SendMessageToSet(&data, false);
20321}
@ SMSG_BREAK_TARGET
Definition: Opcodes.h:368

◆ SendClearThreatListOpcode()

void Unit::SendClearThreatListOpcode ( )
20126{
20127 LOG_DEBUG("entities.unit", "WORLD: Send SMSG_THREAT_CLEAR Message");
20129 data << GetPackGUID();
20130 SendMessageToSet(&data, false);
20131}
@ SMSG_THREAT_CLEAR
Definition: Opcodes.h:1187

◆ SendComboPoints()

void Unit::SendComboPoints ( )
16943{
16944 if (m_cleanupDone)
16945 {
16946 return;
16947 }
16948
16950 if (Player* playerMe = ToPlayer())
16951 {
16952 WorldPacket data(SMSG_UPDATE_COMBO_POINTS, packGUID.size() + 1);
16953 data << packGUID;
16954 data << uint8(m_comboPoints);
16955 playerMe->SendDirectMessage(&data);
16956 }
16957
16958 ObjectGuid ownerGuid = GetCharmerOrOwnerGUID();
16959 Player* owner = nullptr;
16960 if (ownerGuid.IsPlayer())
16961 {
16962 owner = ObjectAccessor::GetPlayer(*this, ownerGuid);
16963 }
16964
16965 if (m_movedByPlayer || owner)
16966 {
16967 WorldPacket data(SMSG_PET_UPDATE_COMBO_POINTS, GetPackGUID().size() + packGUID.size() + 1);
16968 data << GetPackGUID();
16969 data << packGUID;
16970 data << uint8(m_comboPoints);
16971
16972 if (m_movedByPlayer)
16974
16975 if (owner && owner != m_movedByPlayer)
16976 owner->SendDirectMessage(&data);
16977 }
16978}
Definition: ObjectGuid.h:265
std::size_t size() const
Definition: ObjectGuid.h:276
@ SMSG_PET_UPDATE_COMBO_POINTS
Definition: Opcodes.h:1200
@ SMSG_UPDATE_COMBO_POINTS
Definition: Opcodes.h:955

◆ SendEnergizeSpellLog()

void Unit::SendEnergizeSpellLog ( Unit victim,
uint32  SpellID,
uint32  Damage,
Powers  powertype 
)
11205{
11206 WorldPacket data(SMSG_SPELLENERGIZELOG, (8 + 8 + 4 + 4 + 4 + 1));
11207 data << victim->GetPackGUID();
11208 data << GetPackGUID();
11209 data << uint32(spellID);
11210 data << uint32(powerType);
11211 data << uint32(damage);
11212 SendMessageToSet(&data, true);
11213}
@ SMSG_SPELLENERGIZELOG
Definition: Opcodes.h:367

◆ SendHealSpellLog()

void Unit::SendHealSpellLog ( Unit victim,
uint32  SpellID,
uint32  Damage,
uint32  OverHeal,
uint32  Absorb,
bool  critical = false 
)
11176{
11177 // we guess size
11178 WorldPacket data(SMSG_SPELLHEALLOG, (8 + 8 + 4 + 4 + 4 + 4 + 1 + 1));
11179 data << victim->GetPackGUID();
11180 data << GetPackGUID();
11181 data << uint32(SpellID);
11182 data << uint32(Damage);
11183 data << uint32(OverHeal);
11184 data << uint32(Absorb); // Absorb amount
11185 data << uint8(critical ? 1 : 0);
11186 data << uint8(0); // unused
11187 SendMessageToSet(&data, true);
11188}
@ SMSG_SPELLHEALLOG
Definition: Opcodes.h:366

◆ SendMeleeAttackStart()

void Unit::SendMeleeAttackStart ( Unit victim,
Player sendTo = nullptr 
)
3012{
3013 WorldPacket data(SMSG_ATTACKSTART, 8 + 8);
3014 data << GetGUID();
3015 data << victim->GetGUID();
3016 if (sendTo)
3017 sendTo->SendDirectMessage(&data);
3018 else
3019 SendMessageToSet(&data, true);
3020 LOG_DEBUG("entities.unit", "WORLD: Sent SMSG_ATTACKSTART");
3021}
@ SMSG_ATTACKSTART
Definition: Opcodes.h:353

◆ SendMeleeAttackStop()

void Unit::SendMeleeAttackStop ( Unit victim = nullptr)

Can also take the value 0x01, which seems related to updating rotation

3024{
3025 // pussywizard: calling SendMeleeAttackStop without clearing UNIT_STATE_MELEE_ATTACKING and then AttackStart the same player may spoil npc rotating!
3026 // pussywizard: this happens in some boss scripts, just add clearing here
3027 // ClearUnitState(UNIT_STATE_MELEE_ATTACKING); // commented out for now
3028
3029 WorldPacket data(SMSG_ATTACKSTOP, (8 + 8 + 4));
3030 data << GetPackGUID();
3031 data << (victim ? victim->GetPackGUID() : PackedGuid());
3032 data << uint32(0);
3033 SendMessageToSet(&data, true);
3034 LOG_DEBUG("entities.unit", "WORLD: Sent SMSG_ATTACKSTOP");
3035
3036 if (victim)
3037 LOG_DEBUG("entities.unit", "{} {} stopped attacking {} {}", (GetTypeId() == TYPEID_PLAYER ? "Player" : "Creature"), GetGUID().ToString(), (victim->GetTypeId() == TYPEID_PLAYER ? "player" : "creature"), victim->GetGUID().ToString());
3038 else
3039 LOG_DEBUG("entities.unit", "{} {} stopped attacking", (GetTypeId() == TYPEID_PLAYER ? "Player" : "Creature"), GetGUID().ToString());
3040}
@ SMSG_ATTACKSTOP
Definition: Opcodes.h:354

◆ SendMonsterMove()

void Unit::SendMonsterMove ( float  NewPosX,
float  NewPosY,
float  NewPosZ,
uint32  TransitTime,
SplineFlags  sf = SPLINEFLAG_WALK_MODE 
)
556{
557 WorldPacket data(SMSG_MONSTER_MOVE, 1 + 12 + 4 + 1 + 4 + 4 + 4 + 12 + GetPackGUID().size());
558 data << GetPackGUID();
559
560 data << uint8(0); // new in 3.1
561 data << GetPositionX() << GetPositionY() << GetPositionZ();
562 data << GameTime::GetGameTimeMS().count();
563 data << uint8(0);
564 data << uint32(sf);
565 data << TransitTime; // Time in between points
566 data << uint32(1); // 1 single waypoint
567 data << NewPosX << NewPosY << NewPosZ; // the single waypoint Point B
568
569 SendMessageToSet(&data, true);
570}
@ SMSG_MONSTER_MOVE
Definition: Opcodes.h:251

◆ SendMovementFeatherFall()

void Unit::SendMovementFeatherFall ( Player sendTo)
20747{
20748 if (!movespline->Initialized())
20749 return;
20751 data << GetPackGUID();
20752 sendTo->SendDirectMessage(&data);
20753}
bool Initialized() const
Definition: MoveSpline.h:93
@ SMSG_SPLINE_MOVE_FEATHER_FALL
Definition: Opcodes.h:803

◆ SendMovementFlagUpdate()

void Unit::SendMovementFlagUpdate ( bool  self = false)
16791{
16792 WorldPacket data;
16793 BuildHeartBeatMsg(&data);
16794 SendMessageToSet(&data, self);
16795}
void BuildHeartBeatMsg(WorldPacket *data) const
Definition: Object.cpp:2034

◆ SendMovementHover()

void Unit::SendMovementHover ( Player sendTo)
20784{
20785 if (!movespline->Initialized())
20786 return;
20788 data << GetPackGUID();
20789 sendTo->SendDirectMessage(&data);
20790}
@ SMSG_SPLINE_MOVE_SET_HOVER
Definition: Opcodes.h:805

◆ SendMovementWaterWalking()

void Unit::SendMovementWaterWalking ( Player sendTo)
20725{
20726 if (!movespline->Initialized())
20727 return;
20729 data << GetPackGUID();
20730 sendTo->SendDirectMessage(&data);
20731}
@ SMSG_SPLINE_MOVE_WATER_WALK
Definition: Opcodes.h:807

◆ SendPeriodicAuraLog()

void Unit::SendPeriodicAuraLog ( SpellPeriodicAuraLogInfo pInfo)
6290{
6291 AuraEffect const* aura = pInfo->auraEff;
6293 data << GetPackGUID();
6294 data << aura->GetCasterGUID().WriteAsPacked();
6295 data << uint32(aura->GetId()); // spellId
6296 data << uint32(1); // count
6297 data << uint32(aura->GetAuraType()); // auraId
6298 switch (aura->GetAuraType())
6299 {
6302 {
6303 //IF we are in cheat mode we swap absorb with damage and set damage to 0, this way we can still debug damage but our hp bar will not drop
6304 uint32 damage = pInfo->damage;
6305 uint32 absorb = pInfo->absorb;
6306 if (GetTypeId() == TYPEID_PLAYER && ToPlayer()->GetCommandStatus(CHEAT_GOD))
6307 {
6308 absorb = damage;
6309 damage = 0;
6310 }
6311
6312 data << uint32(damage); // damage
6313 data << uint32(pInfo->overDamage); // overkill?
6314 data << uint32(aura->GetSpellInfo()->GetSchoolMask());
6315 data << uint32(absorb); // absorb
6316 data << uint32(pInfo->resist); // resist
6317 data << uint8(pInfo->critical); // new 3.1.2 critical tick
6318 }
6319 break;
6322 data << uint32(pInfo->damage); // damage
6323 data << uint32(pInfo->overDamage); // overheal
6324 data << uint32(pInfo->absorb); // absorb
6325 data << uint8(pInfo->critical); // new 3.1.2 critical tick
6326 break;
6329 data << uint32(aura->GetMiscValue()); // power type
6330 data << uint32(pInfo->damage); // damage
6331 break;
6333 data << uint32(aura->GetMiscValue()); // power type
6334 data << uint32(pInfo->damage); // amount
6335 data << float(pInfo->multiplier); // gain multiplier
6336 break;
6337 default:
6338 LOG_ERROR("entities.unit", "Unit::SendPeriodicAuraLog: unknown aura {}", uint32(aura->GetAuraType()));
6339 return;
6340 }
6341
6342 SendMessageToSet(&data, true);
6343}
@ SPELL_AURA_OBS_MOD_HEALTH
Definition: SpellAuraDefines.h:83
@ SPELL_AURA_PERIODIC_MANA_LEECH
Definition: SpellAuraDefines.h:127
@ SPELL_AURA_PERIODIC_ENERGIZE
Definition: SpellAuraDefines.h:87
@ SMSG_PERIODICAURALOG
Definition: Opcodes.h:620
float multiplier
Definition: Unit.h:940
bool critical
Definition: Unit.h:941
uint32 overDamage
Definition: Unit.h:937
uint32 resist
Definition: Unit.h:939
uint32 damage
Definition: Unit.h:936
AuraEffect const * auraEff
Definition: Unit.h:935
uint32 absorb
Definition: Unit.h:938

◆ SendPetActionFeedback()

void Unit::SendPetActionFeedback ( uint8  msg)

-------—Pet responses methods--------------—

16695{
16696 Unit* owner = GetOwner();
16697 if (!owner || owner->GetTypeId() != TYPEID_PLAYER)
16698 return;
16699
16701 data << uint8(msg);
16702 owner->ToPlayer()->GetSession()->SendPacket(&data);
16703}
@ SMSG_PET_ACTION_FEEDBACK
Definition: Opcodes.h:740

◆ SendPetAIReaction()

void Unit::SendPetAIReaction ( ObjectGuid  guid)
16718{
16719 Unit* owner = GetOwner();
16720 if (!owner || owner->GetTypeId() != TYPEID_PLAYER)
16721 return;
16722
16723 WorldPacket data(SMSG_AI_REACTION, 8 + 4);
16724 data << guid;
16725 data << uint32(AI_REACTION_HOSTILE);
16726 owner->ToPlayer()->GetSession()->SendPacket(&data);
16727}
@ SMSG_AI_REACTION
Definition: Opcodes.h:346

◆ SendPetTalk()

void Unit::SendPetTalk ( uint32  pettalk)
16706{
16707 Unit* owner = GetOwner();
16708 if (!owner || owner->GetTypeId() != TYPEID_PLAYER)
16709 return;
16710
16712 data << GetGUID();
16713 data << uint32(pettalk);
16714 owner->ToPlayer()->GetSession()->SendPacket(&data);
16715}
@ SMSG_PET_ACTION_SOUND
Definition: Opcodes.h:834

◆ SendPlaySpellImpact()

void Unit::SendPlaySpellImpact ( ObjectGuid  guid,
uint32  id 
)
18952{
18954 data << guid; // target
18955 data << uint32(id); // SpellVisualKit.dbc index
18956 SendMessageToSet(&data, true);
18957}
@ SMSG_PLAY_SPELL_IMPACT
Definition: Opcodes.h:533

◆ SendPlaySpellVisual()

void Unit::SendPlaySpellVisual ( uint32  id)
18944{
18946 data << GetGUID();
18947 data << uint32(id); // SpellVisualKit.dbc index
18948 SendMessageToSet(&data, true);
18949}
@ SMSG_PLAY_SPELL_VISUAL
Definition: Opcodes.h:529

◆ SendRemoveFromThreatListOpcode()

void Unit::SendRemoveFromThreatListOpcode ( HostileReference pHostileReference)
20134{
20135 LOG_DEBUG("entities.unit", "WORLD: Send SMSG_THREAT_REMOVE Message");
20136 WorldPacket data(SMSG_THREAT_REMOVE, 8 + 8);
20137 data << GetPackGUID();
20138 data << pHostileReference->getUnitGuid().WriteAsPacked();
20139 SendMessageToSet(&data, false);
20140}
@ SMSG_THREAT_REMOVE
Definition: Opcodes.h:1186

◆ SendSpellDamageImmune()

void Unit::SendSpellDamageImmune ( Unit target,
uint32  spellId 
)
6370{
6371 WorldPacket data(SMSG_SPELLORDAMAGE_IMMUNE, 8 + 8 + 4 + 1);
6372 data << GetGUID();
6373 data << target->GetGUID();
6374 data << uint32(spellId);
6375 data << uint8(0); // bool - log format: 0-default, 1-debug
6376 SendMessageToSet(&data, true);
6377}
@ SMSG_SPELLORDAMAGE_IMMUNE
Definition: Opcodes.h:641

◆ SendSpellDamageResist()

void Unit::SendSpellDamageResist ( Unit target,
uint32  spellId 
)
6360{
6361 WorldPacket data(SMSG_PROCRESIST, 8 + 8 + 4 + 1);
6362 data << GetGUID();
6363 data << target->GetGUID();
6364 data << uint32(spellId);
6365 data << uint8(0); // bool - log format: 0-default, 1-debug
6366 SendMessageToSet(&data, true);
6367}
@ SMSG_PROCRESIST
Definition: Opcodes.h:638

◆ SendSpellMiss()

void Unit::SendSpellMiss ( Unit target,
uint32  spellID,
SpellMissInfo  missInfo 
)
6346{
6347 WorldPacket data(SMSG_SPELLLOGMISS, (4 + 8 + 1 + 4 + 8 + 1));
6348 data << uint32(spellID);
6349 data << GetGUID();
6350 data << uint8(0); // can be 0 or 1
6351 data << uint32(1); // target count
6352 // for (i = 0; i < target count; ++i)
6353 data << target->GetGUID(); // target GUID
6354 data << uint8(missInfo);
6355 // end loop
6356 SendMessageToSet(&data, true);
6357}
@ SMSG_SPELLLOGMISS
Definition: Opcodes.h:617

◆ SendSpellNonMeleeDamageLog() [1/2]

void Unit::SendSpellNonMeleeDamageLog ( SpellNonMeleeDamage log)
6211{
6212 WorldPacket data(SMSG_SPELLNONMELEEDAMAGELOG, (16 + 4 + 4 + 4 + 1 + 4 + 4 + 1 + 1 + 4 + 4 + 1)); // we guess size
6213 //IF we are in cheat mode we swap absorb with damage and set damage to 0, this way we can still debug damage but our hp bar will not drop
6214 uint32 damage = log->damage;
6215 uint32 absorb = log->absorb;
6217 {
6218 absorb = damage;
6219 damage = 0;
6220 }
6221 data << log->target->GetPackGUID();
6222 data << log->attacker->GetPackGUID();
6223 data << uint32(log->spellInfo->Id);
6224 data << uint32(damage); // damage amount
6225 int32 overkill = damage - log->target->GetHealth();
6226 data << uint32(overkill > 0 ? overkill : 0); // overkill
6227 data << uint8 (log->schoolMask); // damage school
6228 data << uint32(absorb); // AbsorbedDamage
6229 data << uint32(log->resist); // resist
6230 data << uint8 (log->physicalLog); // if 1, then client show spell name (example: %s's ranged shot hit %s for %u school or %s suffers %u school damage from %s's spell_name
6231 data << uint8 (log->unused); // unused
6232 data << uint32(log->blocked); // blocked
6233 data << uint32(log->HitInfo);
6234 data << uint32(log->HitInfo);
6236 //if (log->HitInfo & SPELL_HIT_TYPE_CRIT_DEBUG)
6237 //{
6238 // data << float(log->CritRoll);
6239 // data << float(log->CritNeeded);
6240 //}
6241 //if (log->HitInfo & SPELL_HIT_TYPE_HIT_DEBUG)
6242 //{
6243 // data << float(log->HitRoll);
6244 // data << float(log->HitNeeded);
6245 //}
6246 //if (log->HitInfo & SPELL_HIT_TYPE_ATTACK_TABLE_DEBUG)
6247 //{
6248 // data << float(log->MissChance);
6249 // data << float(log->DodgeChance);
6250 // data << float(log->ParryChance);
6251 // data << float(log->BlockChance);
6252 // data << float(log->GlanceChance);
6253 // data << float(log->CrushChance);
6254 //}
6255 SendMessageToSet(&data, true);
6256}
@ SPELL_HIT_TYPE_HIT_DEBUG
Definition: SharedDefines.h:1509
@ SPELL_HIT_TYPE_ATTACK_TABLE_DEBUG
Definition: SharedDefines.h:1512
@ SPELL_HIT_TYPE_CRIT_DEBUG
Definition: SharedDefines.h:1507
@ SMSG_SPELLNONMELEEDAMAGELOG
Definition: Opcodes.h:622
bool physicalLog
Definition: Unit.h:922
bool unused
Definition: Unit.h:923

◆ SendSpellNonMeleeDamageLog() [2/2]

void Unit::SendSpellNonMeleeDamageLog ( Unit target,
SpellInfo const *  spellInfo,
uint32  Damage,
SpellSchoolMask  damageSchoolMask,
uint32  AbsorbedDamage,
uint32  Resist,
bool  PhysicalDamage,
uint32  Blocked,
bool  CriticalHit = false,
bool  Split = false 
)
6259{
6260 SpellNonMeleeDamage log(this, target, spellInfo, damageSchoolMask);
6261 log.damage = Damage;
6262 log.absorb = AbsorbedDamage;
6263 log.resist = Resist;
6264 log.physicalLog = PhysicalDamage;
6265 log.blocked = Blocked;
6266 log.HitInfo = 0;
6267 if (CriticalHit)
6268 {
6269 log.HitInfo |= SPELL_HIT_TYPE_CRIT;
6270 }
6271 if (Split)
6272 {
6273 log.HitInfo |= SPELL_HIT_TYPE_SPLIT;
6274 }
6276}
@ SPELL_HIT_TYPE_SPLIT
Definition: SharedDefines.h:1510
Definition: Unit.h:908

◆ SendSpellNonMeleeReflectLog()

void Unit::SendSpellNonMeleeReflectLog ( SpellNonMeleeDamage log,
Unit attacker 
)
6179{
6180 // Xinef: function for players only, placed in unit because of cosmetics
6181 if (GetTypeId() != TYPEID_PLAYER)
6182 return;
6183
6184 WorldPacket data(SMSG_SPELLNONMELEEDAMAGELOG, (16 + 4 + 4 + 4 + 1 + 4 + 4 + 1 + 1 + 4 + 4 + 1)); // we guess size
6185 //IF we are in cheat mode we swap absorb with damage and set damage to 0, this way we can still debug damage but our hp bar will not drop
6186 uint32 damage = log->damage;
6187 uint32 absorb = log->absorb;
6189 {
6190 absorb = damage;
6191 damage = 0;
6192 }
6193 data << log->target->GetPackGUID();
6194 data << attacker->GetPackGUID();
6195 data << uint32(log->spellInfo->Id);
6196 data << uint32(damage); // damage amount
6197 int32 overkill = damage - log->target->GetHealth();
6198 data << uint32(overkill > 0 ? overkill : 0); // overkill
6199 data << uint8 (log->schoolMask); // damage school
6200 data << uint32(absorb); // AbsorbedDamage
6201 data << uint32(log->resist); // resist
6202 data << uint8 (log->physicalLog); // if 1, then client show spell name (example: %s's ranged shot hit %s for %u school or %s suffers %u school damage from %s's spell_name
6203 data << uint8 (log->unused); // unused
6204 data << uint32(log->blocked); // blocked
6205 data << uint32(log->HitInfo);
6206 data << uint8 (0); // flag to use extend data
6207 ToPlayer()->SendDirectMessage(&data);
6208}

◆ SendTameFailure()

void Unit::SendTameFailure ( uint8  result)
20009{
20011 data << uint8(result);
20012 ToPlayer()->SendDirectMessage(&data);
20013}
@ SMSG_PET_TAME_FAILURE
Definition: Opcodes.h:401

◆ SendTeleportPacket()

void Unit::SendTeleportPacket ( Position pos)
20016{
20018 if (GetTypeId() == TYPEID_UNIT)
20019 Relocate(&pos);
20020
20021 WorldPacket data2(MSG_MOVE_TELEPORT, 38);
20022 data2 << GetPackGUID();
20023 BuildMovementPacket(&data2);
20024 if (GetTypeId() == TYPEID_UNIT)
20025 Relocate(&oldPos);
20026 if (GetTypeId() == TYPEID_PLAYER)
20027 Relocate(&pos);
20028 SendMessageToSet(&data2, false);
20029}
@ MSG_MOVE_TELEPORT
Definition: Opcodes.h:227

◆ SendThreatListUpdate()

void Unit::SendThreatListUpdate ( )
20085{
20086 if (!GetThreatMgr().isThreatListEmpty())
20087 {
20088 uint32 count = GetThreatMgr().GetThreatList().size();
20089
20090 //LOG_DEBUG("entities.unit", "WORLD: Send SMSG_THREAT_UPDATE Message");
20091 WorldPacket data(SMSG_THREAT_UPDATE, 8 + count * 8);
20092 data << GetPackGUID();
20093 data << uint32(count);
20095 for (ThreatContainer::StorageType::const_iterator itr = tlist.begin(); itr != tlist.end(); ++itr)
20096 {
20097 data << (*itr)->getUnitGuid().WriteAsPacked();
20098 data << uint32((*itr)->GetThreat() * 100);
20099 }
20100 SendMessageToSet(&data, false);
20101 }
20102}
@ SMSG_THREAT_UPDATE
Definition: Opcodes.h:1185

◆ SetAI()

void Unit::SetAI ( UnitAI newAI)
inline
1317{ i_AI = newAI; }

◆ SetArmor()

void Unit::SetArmor ( int32  val)
inline
void SetResistance(SpellSchools school, int32 val)
Definition: Unit.h:1435

◆ SetAttackTime()

void Unit::SetAttackTime ( WeaponAttackType  att,
uint32  val 
)
inline
1473{ SetFloatValue(static_cast<uint16>(UNIT_FIELD_BASEATTACKTIME) + att, val * m_modAttackSpeedPct[att]); }
void SetFloatValue(uint16 index, float value)
Definition: Object.cpp:737

◆ setAttackTimer()

void Unit::setAttackTimer ( WeaponAttackType  type,
int32  time 
)
inline
1340{ m_attackTimer[type] = time; }

◆ SetAuraStack()

void Unit::SetAuraStack ( uint32  spellId,
Unit target,
uint32  stack 
)
18935{
18936 Aura* aura = target->GetAura(spellId, GetGUID());
18937 if (!aura)
18938 aura = AddAura(spellId, target);
18939 if (aura && stack)
18940 aura->SetStackAmount(stack);
18941}
void SetStackAmount(uint8 num)
Definition: SpellAuras.cpp:1009

◆ SetBaseWeaponDamage()

void Unit::SetBaseWeaponDamage ( WeaponAttackType  attType,
WeaponDamageRange  damageRange,
float  value,
uint8  damageIndex = 0 
)
inline
2115{ m_weaponDamage[attType][damageRange][damageIndex] = value; }

◆ SetCanDualWield()

virtual void Unit::SetCanDualWield ( bool  value)
inlinevirtual

Reimplemented in Creature.

1346{ m_canDualWield = value; }

◆ SetCanFly()

bool Unit::SetCanFly ( bool  enable,
bool  packetOnly = false 
)
virtual

Reimplemented in Player, and Creature.

20694{
20696 return false;
20697
20698 if (enable)
20699 {
20702 }
20703 else
20704 {
20706 }
20707
20708 return true;
20709}
@ MOVEMENTFLAG_CAN_FLY
Definition: Unit.h:576
@ MOVEMENTFLAG_MASK_MOVING_FLY
Definition: Unit.h:593
void AddUnitMovementFlag(uint32 f)
Definition: Unit.h:2267

◆ SetCanModifyStats()

void Unit::SetCanModifyStats ( bool  modifyStats)
inline
2103{ m_canModifyStats = modifyStats; }

◆ SetCantProc()

void Unit::SetCantProc ( bool  apply)
inline
2317 {
2318 if (apply)
2319 ++m_procDeep;
2320 else
2321 {
2323 --m_procDeep;
2324 }
2325 }

◆ SetCharm()

void Unit::SetCharm ( Unit target,
bool  apply 
)
10825{
10826 if (apply)
10827 {
10828 if (GetTypeId() == TYPEID_PLAYER)
10829 {
10830 if (!AddGuidValue(UNIT_FIELD_CHARM, charm->GetGUID()))
10831 LOG_FATAL("entities.unit", "Player {} is trying to charm unit {}, but it already has a charmed unit {}", GetName(), charm->GetEntry(), GetCharmGUID().ToString());
10832
10833 charm->m_ControlledByPlayer = true;
10834 // TODO: maybe we can use this flag to check if controlled by player
10835 charm->SetUnitFlag(UNIT_FLAG_PLAYER_CONTROLLED);
10836 }
10837 else
10838 charm->m_ControlledByPlayer = false;
10839
10840 // PvP, FFAPvP
10841 charm->SetByteValue(UNIT_FIELD_BYTES_2, 1, GetByteValue(UNIT_FIELD_BYTES_2, 1));
10842
10843 if (!charm->AddGuidValue(UNIT_FIELD_CHARMEDBY, GetGUID()))
10844 LOG_FATAL("entities.unit", "Unit {} is being charmed, but it already has a charmer {}", charm->GetEntry(), charm->GetCharmerGUID().ToString());
10845
10846 _isWalkingBeforeCharm = charm->IsWalking();
10848 {
10849 charm->SetWalk(false);
10850 charm->SendMovementFlagUpdate();
10851 }
10852
10853 m_Controlled.insert(charm);
10854 }
10855 else
10856 {
10857 if (GetTypeId() == TYPEID_PLAYER)
10858 {
10859 if (!RemoveGuidValue(UNIT_FIELD_CHARM, charm->GetGUID()))
10860 LOG_FATAL("entities.unit", "Player {} is trying to uncharm unit {}, but it has another charmed unit {}", GetName(), charm->GetEntry(), GetCharmGUID().ToString());
10861 }
10862
10863 if (!charm->RemoveGuidValue(UNIT_FIELD_CHARMEDBY, GetGUID()))
10864 LOG_FATAL("entities.unit", "Unit {} is being uncharmed, but it has another charmer {}", charm->GetEntry(), charm->GetCharmerGUID().ToString());
10865
10866 if (charm->GetTypeId() == TYPEID_PLAYER)
10867 {
10868 charm->m_ControlledByPlayer = true;
10869 charm->SetUnitFlag(UNIT_FLAG_PLAYER_CONTROLLED);
10870 charm->ToPlayer()->UpdatePvPState();
10871 }
10872 else if (Player* player = charm->GetCharmerOrOwnerPlayerOrPlayerItself())
10873 {
10874 charm->m_ControlledByPlayer = true;
10875 charm->SetUnitFlag(UNIT_FLAG_PLAYER_CONTROLLED);
10876 charm->SetByteValue(UNIT_FIELD_BYTES_2, 1, player->GetByteValue(UNIT_FIELD_BYTES_2, 1));
10877
10878 // Xinef: skip controlled erase if charmed unit is owned by charmer
10879 if (charm->IsInWorld() && !charm->IsDuringRemoveFromWorld() && player->GetGUID() == this->GetGUID() && (charm->IsPet() || charm->HasUnitTypeMask(UNIT_MASK_MINION)))
10880 return;
10881 }
10882 else
10883 {
10884 charm->m_ControlledByPlayer = false;
10885 charm->RemoveUnitFlag(UNIT_FLAG_PLAYER_CONTROLLED);
10886 charm->SetByteValue(UNIT_FIELD_BYTES_2, 1, 0);
10887 }
10888
10889 if (charm->IsWalking() != _isWalkingBeforeCharm)
10890 {
10891 charm->SetWalk(_isWalkingBeforeCharm);
10892 charm->SendMovementFlagUpdate(true); // send packet to self, to update movement state on player.
10893 }
10894
10895 m_Controlled.erase(charm);
10896 }
10897}
bool AddGuidValue(uint16 index, ObjectGuid value)
Definition: Object.cpp:686
bool RemoveGuidValue(uint16 index, ObjectGuid value)
Definition: Object.cpp:704

◆ SetCharmedBy()

bool Unit::SetCharmedBy ( Unit charmer,
CharmType  type,
AuraApplication const *  aurApp = nullptr 
)
18386{
18387 if (!charmer)
18388 return false;
18389
18390 if (!charmer->IsInWorld() || charmer->IsDuringRemoveFromWorld())
18391 {
18392 return false;
18393 }
18394
18395 // dismount players when charmed
18396 if (GetTypeId() == TYPEID_PLAYER)
18398
18399 if (charmer->GetTypeId() == TYPEID_PLAYER)
18401
18402 ASSERT(type != CHARM_TYPE_POSSESS || charmer->GetTypeId() == TYPEID_PLAYER);
18403 if (type == CHARM_TYPE_VEHICLE && !IsVehicle()) // pussywizard
18404 throw 1;
18405 ASSERT((type == CHARM_TYPE_VEHICLE) == IsVehicle());
18406
18407 LOG_DEBUG("entities.unit", "SetCharmedBy: charmer {} ({}), charmed {} ({}), type {}.",
18408 charmer->GetEntry(), charmer->GetGUID().ToString(), GetEntry(), GetGUID().ToString(), uint32(type));
18409
18410 if (this == charmer)
18411 {
18412 LOG_FATAL("entities.unit", "Unit::SetCharmedBy: Unit {} ({}) is trying to charm itself!", GetEntry(), GetGUID().ToString());
18413 return false;
18414 }
18415
18416 //if (HasUnitState(UNIT_STATE_UNATTACKABLE))
18417 // return false;
18418
18420 {
18421 LOG_FATAL("entities.unit", "Unit::SetCharmedBy: Player on transport is trying to charm {} ({})", GetEntry(), GetGUID().ToString());
18422 return false;
18423 }
18424
18425 // Already charmed
18426 if (GetCharmerGUID())
18427 {
18428 LOG_FATAL("entities.unit", "Unit::SetCharmedBy: {} ({}) has already been charmed but {} ({}) is trying to charm it!",
18429 GetEntry(), GetGUID().ToString(), charmer->GetEntry(), charmer->GetGUID().ToString());
18430 return false;
18431 }
18432
18433 CastStop();
18434 AttackStop();
18435
18436 // Xinef: dont reset threat and combat, put them on offline list, moved down after faction changes
18437 // CombatStop(); // TODO: CombatStop(true) may cause crash (interrupt spells)
18438 // DeleteThreatList();
18439
18440 Player* playerCharmer = charmer->ToPlayer();
18441
18442 // Charmer stop charming
18443 if (playerCharmer)
18444 {
18445 playerCharmer->StopCastingCharm();
18446 playerCharmer->StopCastingBindSight();
18447 }
18448
18449 // Charmed stop charming
18450 if (GetTypeId() == TYPEID_PLAYER)
18451 {
18454 }
18455
18456 // StopCastingCharm may remove a possessed pet?
18457 if (!IsInWorld())
18458 {
18459 LOG_FATAL("entities.unit", "Unit::SetCharmedBy: {} ({}) is not in world but {} ({}) is trying to charm it!",
18460 GetEntry(), GetGUID().ToString(), charmer->GetEntry(), charmer->GetGUID().ToString());
18461 return false;
18462 }
18463
18464 // charm is set by aura, and aura effect remove handler was called during apply handler execution
18465 // prevent undefined behaviour
18466 if (aurApp && aurApp->GetRemoveMode())
18467 return false;
18468
18470 SetFaction(charmer->GetFaction());
18471
18472 // Set charmed
18473 charmer->SetCharm(this, true);
18474
18476
18477 if (GetTypeId() == TYPEID_UNIT)
18478 {
18479 GetMotionMaster()->Clear(false);
18481 StopMoving();
18482
18483 if (charmer->GetTypeId() == TYPEID_PLAYER && charmer->getClass() == CLASS_WARLOCK && ToCreature()->GetCreatureTemplate()->type == CREATURE_TYPE_DEMON)
18484 {
18485 // Disable CreatureAI/SmartAI and switch to CharmAI when charmed by warlock
18486 Creature* charmed = ToCreature();
18487 charmed->NeedChangeAI = true;
18488 charmed->IsAIEnabled = false;
18489 }
18490 else
18491 {
18492 ToCreature()->AI()->OnCharmed(true);
18493 }
18494
18495 // Xinef: If creature can fly, add normal player flying flag (fixes speed)
18496 if (charmer->GetTypeId() == TYPEID_PLAYER && ToCreature()->CanFly())
18498 }
18499 else
18500 {
18501 Player* player = ToPlayer();
18502 if (player->isAFK())
18503 player->ToggleAFK();
18504
18505 player->SetClientControl(this, false); // verified
18506 }
18507
18508 // charm is set by aura, and aura effect remove handler was called during apply handler execution
18509 // prevent undefined behaviour
18510 if (aurApp && aurApp->GetRemoveMode())
18511 return false;
18512
18513 // Pets already have a properly initialized CharmInfo, don't overwrite it.
18514 // Xinef: I need charmInfo for vehicle
18515 if (/*type != CHARM_TYPE_VEHICLE &&*/ !GetCharmInfo())
18516 {
18517 InitCharmInfo();
18518 if (type == CHARM_TYPE_POSSESS)
18520 else if (type != CHARM_TYPE_VEHICLE)
18521 {
18523
18524 // Xinef: convert charm npcs dont have pet bar so initialize them as defensive helpers
18525 if (type == CHARM_TYPE_CONVERT && GetTypeId() == TYPEID_UNIT)
18527 }
18528 }
18529
18530 if (playerCharmer)
18531 {
18532 switch (type)
18533 {
18534 case CHARM_TYPE_VEHICLE:
18537 playerCharmer->SetClientControl(this, true); // verified
18538 playerCharmer->VehicleSpellInitialize();
18539 break;
18540 case CHARM_TYPE_POSSESS:
18545 playerCharmer->SetClientControl(this, true); // verified
18546 playerCharmer->PossessSpellInitialize();
18547 break;
18548 case CHARM_TYPE_CHARM:
18549 if (GetTypeId() == TYPEID_UNIT && charmer->getClass() == CLASS_WARLOCK)
18550 {
18552 if (cinfo && cinfo->type == CREATURE_TYPE_DEMON)
18553 {
18554 // to prevent client crash
18556
18557 // just to enable stat window
18558 if (GetCharmInfo())
18559 GetCharmInfo()->SetPetNumber(sObjectMgr->GeneratePetNumber(), true);
18560
18561 // if charmed two demons the same session, the 2nd gets the 1st one's name
18562 SetUInt32Value(UNIT_FIELD_PET_NAME_TIMESTAMP, uint32(GameTime::GetGameTime().count())); // cast can't be helped
18563 }
18564 }
18566 playerCharmer->CharmSpellInitialize();
18567 break;
18568 default:
18569 break;
18570 }
18571 }
18572 else if (GetTypeId() == TYPEID_PLAYER)
18574
18575 if (Creature* creature = ToCreature())
18576 creature->RefreshSwimmingFlag();
18577
18578 if (GetTypeId() == TYPEID_PLAYER)
18579 sScriptMgr->OnPlayerBeingCharmed(ToPlayer(), charmer, _oldFactionId, charmer->GetFaction());
18580
18581 return true;
18582}
@ SPELL_AURA_MOD_SHAPESHIFT
Definition: SpellAuraDefines.h:99
@ REACT_DEFENSIVE
Definition: Unit.h:1024
@ CHARM_TYPE_CONVERT
Definition: Unit.h:1078
@ UNIT_FIELD_PET_NAME_TIMESTAMP
Definition: UpdateFields.h:133
void OnCharmed(bool apply) override
Definition: CreatureAI.cpp:48
void SetReactState(ReactStates st)
Definition: Creature.h:88
void MoveIdle()
Definition: MotionMaster.cpp:231
void CharmSpellInitialize()
Definition: Player.cpp:9506
void ToggleAFK()
Definition: Player.cpp:1272
void PossessSpellInitialize()
Definition: Player.cpp:9403
void StopCastingBindSight()
Definition: Player.cpp:12865
bool isAFK() const
Definition: Player.h:1114
void VehicleSpellInitialize()
Definition: Player.cpp:9431
virtual float GetFollowAngle() const
Definition: Unit.h:2387
CharmInfo * InitCharmInfo()
Definition: Unit.cpp:15649
void InitPossessCreateSpells()
Definition: Unit.cpp:15717
void InitCharmCreateSpells()
Definition: Unit.cpp:15753

◆ SetCharmerGUID()

void Unit::SetCharmerGUID ( ObjectGuid  owner)
inline

◆ SetCombatTimer()

void Unit::SetCombatTimer ( uint32  timer)
inline
1696{ m_CombatTimer = timer; }

◆ SetConfused()

void Unit::SetConfused ( bool  apply)
protected
18349{
18350 if (apply)
18351 {
18352 SetTarget();
18354
18355 if (GetTypeId() == TYPEID_PLAYER)
18356 {
18357 sScriptMgr->AnticheatSetSkipOnePacketForASH(ToPlayer(), true);
18358 }
18359 }
18360 else
18361 {
18362 if (IsAlive())
18363 {
18364 if (GetMotionMaster()->GetMotionSlotType(MOTION_SLOT_CONTROLLED) == CONFUSED_MOTION_TYPE)
18365 {
18367 StopMoving();
18368 }
18369
18370 if (GetVictim())
18372 }
18373 }
18374
18375 // xinef: block / allow control to real mover (eg. charmer)
18376 if (GetTypeId() == TYPEID_PLAYER)
18377 {
18378 if (m_movedByPlayer)
18379 m_movedByPlayer->ToPlayer()->SetClientControl(this, !apply); // verified
18380 //else
18381 // ToPlayer()->SetClientControl(this, !apply);
18382 }
18383}
@ CONFUSED_MOTION_TYPE
Definition: MotionMaster.h:42
void MoveConfused()
Definition: MotionMaster.cpp:281

◆ SetContestedPvP()

void Unit::SetContestedPvP ( Player attackedPlayer = nullptr,
bool  lookForNearContestedGuards = true 
)
17310{
17312
17313 if (!player || ((attackedPlayer && (attackedPlayer == player || (player->duel && player->duel->Opponent == attackedPlayer))) || player->InBattleground()))
17314 return;
17315
17316 // check if there any guards that should care about the contested flag on player
17317 if (lookForNearContestedGuards)
17318 {
17319 std::list<Unit*> targets;
17322 Cell::VisitAllObjects(this, searcher, MAX_AGGRO_RADIUS);
17323
17324 // return if there are no contested guards found
17325 if (!targets.size())
17326 {
17327 return;
17328 }
17329 }
17330
17331 player->SetContestedPvPTimer(30000);
17333 {
17336 // call MoveInLineOfSight for nearby contested guards
17338 }
17340 {
17342 // call MoveInLineOfSight for nearby contested guards
17344 }
17345}
#define MAX_AGGRO_RADIUS
Definition: Unit.h:162
void SetPlayerFlag(PlayerFlags flags)
Definition: Player.h:1091
bool InBattleground() const
Definition: Player.h:2200
void SetContestedPvPTimer(uint32 newTime)
Definition: Player.h:1818

◆ SetControlled()

void Unit::SetControlled ( bool  apply,
UnitState  state 
)
18072{
18073 if (apply)
18074 {
18075 if (HasUnitState(state))
18076 return;
18077
18078 AddUnitState(state);
18079 switch (state)
18080 {
18081 case UNIT_STATE_STUNNED:
18082 SetStunned(true);
18083 break;
18084 case UNIT_STATE_ROOT:
18086 SetRooted(true);
18087 break;
18090 {
18093 // SendAutoRepeatCancel ?
18094 SetConfused(true);
18095 CastStop(0, false);
18096 }
18097 break;
18098 case UNIT_STATE_FLEEING:
18100 {
18103 // SendAutoRepeatCancel ?
18104 SetFeared(true);
18105 CastStop(0, false);
18106 }
18107 break;
18108 default:
18109 break;
18110 }
18111
18112 if (GetTypeId() == TYPEID_PLAYER)
18113 {
18114 sScriptMgr->AnticheatSetRootACKUpd(ToPlayer());
18115 }
18116 }
18117 else
18118 {
18119 // xinef: moved from below, checked all SetX functions, no calls to currently modified state
18120 // xinef: added to each case because of return
18121 //ClearUnitState(state);
18122
18123 switch (state)
18124 {
18125 case UNIT_STATE_STUNNED:
18127 return;
18128 ClearUnitState(state);
18129 SetStunned(false);
18130 break;
18131 case UNIT_STATE_ROOT:
18132 // Prevent creature_template_movement rooted flag from being removed on aura expiration.
18133 if (GetTypeId() == TYPEID_UNIT)
18134 {
18135 if (ToCreature()->GetCreatureTemplate()->Movement.Rooted)
18136 {
18137 return;
18138 }
18139 }
18140
18142 return;
18143 ClearUnitState(state);
18144 SetRooted(false);
18145 break;
18148 return;
18149 ClearUnitState(state);
18150 SetConfused(false);
18151 break;
18152 case UNIT_STATE_FLEEING:
18154 return;
18155 ClearUnitState(state);
18156 SetFeared(false);
18157 break;
18158 default:
18159 return;
18160 }
18161
18162 //ClearUnitState(state);
18163
18165 SetStunned(true);
18166 else
18167 {
18169 SetRooted(true);
18170
18172 SetConfused(true);
18174 SetFeared(true);
18175 }
18176 }
18177}
void SetConfused(bool apply)
Definition: Unit.cpp:18348
void SetStunned(bool apply)
Definition: Unit.cpp:18179
void SetRooted(bool apply, bool isStun=false)
Definition: Unit.cpp:18222
void SetFeared(bool apply)
Definition: Unit.cpp:18304
Definition: Unit.h:688

◆ SetCreateHealth()

void Unit::SetCreateHealth ( uint32  val)
inline

◆ SetCreateMana()

void Unit::SetCreateMana ( uint32  val)
inline

◆ SetCreateStat()

void Unit::SetCreateStat ( Stats  stat,
float  val 
)
inline
2034{ m_createStats[stat] = val; }

◆ SetCreatorGUID()

void Unit::SetCreatorGUID ( ObjectGuid  creator)
inline

◆ SetCritterGUID()

void Unit::SetCritterGUID ( ObjectGuid  guid)
inline

◆ SetCurrentCastedSpell()

void Unit::SetCurrentCastedSpell ( Spell pSpell)
3898{
3899 ASSERT(pSpell); // nullptr may be never passed here, use InterruptSpell or InterruptNonMeleeSpells
3900
3901 CurrentSpellTypes CSpellType = pSpell->GetCurrentContainer();
3902
3903 if (pSpell == m_currentSpells[CSpellType]) // avoid breaking self
3904 return;
3905
3906 bool bySelf = m_currentSpells[CSpellType] && m_currentSpells[CSpellType]->m_spellInfo->Id == pSpell->m_spellInfo->Id;
3907
3908 // break same type spell if it is not delayed
3909 InterruptSpell(CSpellType, false, true, bySelf);
3910
3911 // special breakage effects:
3912 switch (CSpellType)
3913 {
3915 {
3916 // generic spells always break channeled not delayed spells
3918 {
3919 if (!s->GetSpellInfo()->IsActionAllowedChannel())
3920 {
3922 }
3923 }
3924
3925 // autorepeat breaking
3927 {
3928 // break autorepeat if not Auto Shot
3929 if (m_currentSpells[CURRENT_AUTOREPEAT_SPELL]->m_spellInfo->Id != 75)
3931 m_AutoRepeatFirstCast = true;
3932 }
3933 if (pSpell->GetCastTime() > 0)
3935
3936 break;
3937 }
3939 {
3940 // channel spells always break generic non-delayed and any channeled spells
3942 InterruptSpell(CURRENT_CHANNELED_SPELL, true, true, bySelf);
3943
3944 // it also does break autorepeat if not Auto Shot
3946 m_currentSpells[CURRENT_AUTOREPEAT_SPELL]->m_spellInfo->Id != 75)
3949
3950 break;
3951 }
3953 {
3954 // only Auto Shoot does not break anything
3955 if (pSpell->m_spellInfo->Id != 75)
3956 {
3957 // generic autorepeats break generic non-delayed and channeled non-delayed spells
3959 {
3960 if (!s->GetSpellInfo()->IsActionAllowedChannel())
3961 {
3963 }
3964 }
3965
3967 }
3968 // special action: set first cast flag
3969 m_AutoRepeatFirstCast = true;
3970
3971 break;
3972 }
3973
3974 default:
3975 // other spell types don't break anything now
3976 break;
3977 }
3978
3979 // current spell (if it is still here) may be safely deleted now
3980 if (m_currentSpells[CSpellType])
3981 m_currentSpells[CSpellType]->SetReferencedFromCurrent(false);
3982
3983 // set new current spell
3984 m_currentSpells[CSpellType] = pSpell;
3985 pSpell->SetReferencedFromCurrent(true);
3986
3987 pSpell->m_selfContainer = &(m_currentSpells[pSpell->GetCurrentContainer()]);
3988}
CurrentSpellTypes GetCurrentContainer() const
Definition: Spell.cpp:7862
Spell ** m_selfContainer
Definition: Spell.h:609

◆ setDeathState()

void Unit::setDeathState ( DeathState  s,
bool  despawn = false 
)
virtual

Reimplemented in Creature, Minion, Pet, and Player.

14426{
14427 // death state needs to be updated before RemoveAllAurasOnDeath() calls HandleChannelDeathItem(..) so that
14428 // it can be used to check creation of death items (such as soul shards).
14429
14430 if (s != ALIVE && s != JUST_RESPAWNED)
14431 {
14432 CombatStop();
14435 ClearComboPointHolders(); // any combo points pointed to unit lost at it death
14436
14437 if (IsNonMeleeSpellCast(false))
14439
14440 UnsummonAllTotems(true);
14441 RemoveAllControlled(true);
14443 }
14444
14445 if (s == JUST_DIED)
14446 {
14447 // remove aurastates allowing special moves
14450
14451 GetMotionMaster()->Clear(false);
14453
14454 // Xinef: Remove Hover so the corpse can fall to the ground
14455 SetHover(false);
14456
14457 if (despawn)
14458 DisableSpline();
14459 else
14460 StopMoving();
14461
14462 // without this when removing IncreaseMaxHealth aura player may stuck with 1 hp
14463 // do not why since in IncreaseMaxHealth currenthealth is checked
14464 SetHealth(0);
14465 SetPower(getPowerType(), 0);
14466
14467 // players in instance don't have ZoneScript, but they have InstanceScript
14469 zoneScript->OnUnitDeath(this);
14470 }
14471 else if (s == JUST_RESPAWNED)
14472 {
14473 RemoveFlag (UNIT_FIELD_FLAGS, UNIT_FLAG_SKINNABLE); // clear skinnable for creature and player (at battleground)
14474 }
14475
14476 m_deathState = s;
14477}
@ JUST_RESPAWNED
Definition: Unit.h:320
@ UNIT_FLAG_SKINNABLE
Definition: Unit.h:474
void ClearAllReactives()
Definition: Unit.cpp:16988
virtual bool SetHover(bool enable, bool packetOnly=false, bool updateAnimationTier=true)
Definition: Unit.cpp:20755
void ClearDiminishings()
Definition: Unit.h:1332
InstanceScript * GetInstanceScript() const
Definition: Object.cpp:1192
ZoneScript * GetZoneScript() const
Definition: Object.h:523
Definition: ZoneScript.h:27

◆ SetDisableGravity()

bool Unit::SetDisableGravity ( bool  disable,
bool  packetOnly = false,
bool  updateAnimationTier = true 
)
virtual

Reimplemented in Creature, and Player.

20657{
20658 if (disable == IsLevitating())
20659 return false;
20660
20661 if (disable)
20662 {
20665 }
20666 else
20667 {
20669 }
20670
20671 return true;
20672}
bool IsLevitating() const
Definition: Unit.h:2373

◆ SetDisplayId()

void Unit::SetDisplayId ( uint32  modelId)
virtual

Reimplemented in Creature, and Pet.

16841{
16843 // Set Gender by modelId
16844 if (CreatureModelInfo const* minfo = sObjectMgr->GetCreatureModelInfo(modelId))
16845 SetByteValue(UNIT_FIELD_BYTES_0, 2, minfo->gender);
16846
16847 sScriptMgr->OnDisplayIdChange(this, modelId);
16848}
Definition: CreatureData.h:388

◆ SetExtraUnitMovementFlags()

void Unit::SetExtraUnitMovementFlags ( uint16  f)
inline
2277{ m_movementInfo.flags2 = f; }

◆ SetFacingTo()

void Unit::SetFacingTo ( float  ori)
20620{
20621 Movement::MoveSplineInit init(this);
20622 init.MoveTo(GetPositionX(), GetPositionY(), GetPositionZ(), false);
20624 init.DisableTransportPathTransformations(); // It makes no sense to target global orientation
20625 init.SetFacing(ori);
20626 init.Launch();
20627}
ObjectGuid GetTransGUID() const override
Definition: Unit.cpp:18788

◆ SetFacingToObject()

void Unit::SetFacingToObject ( WorldObject object)
Todo:
figure out under what conditions creature will move towards object instead of facing it where it currently is.
20630{
20631 // never face when already moving
20632 if (!IsStopped())
20633 return;
20634
20636 Movement::MoveSplineInit init(this);
20637 init.MoveTo(GetPositionX(), GetPositionY(), GetPositionZ());
20638 init.SetFacing(GetAngle(object)); // when on transport, GetAngle will still return global coordinates (and angle) that needs transforming
20639 init.Launch();
20640}
bool IsStopped() const
Definition: Unit.h:2261

◆ SetFaction()

void Unit::SetFaction ( uint32  faction)
10018{
10020 if (GetTypeId() == TYPEID_UNIT)
10022}
void UpdateMoveInLineOfSightState()
Definition: Creature.cpp:2494

◆ SetFeared()

void Unit::SetFeared ( bool  apply)
protected
18305{
18306 if (apply)
18307 {
18308 SetTarget();
18309
18310 Unit* caster = nullptr;
18312 if (!fearAuras.empty())
18313 caster = ObjectAccessor::GetUnit(*this, fearAuras.front()->GetCasterGUID());
18314 if (!caster)
18315 caster = getAttackerForHelper();
18316 GetMotionMaster()->MoveFleeing(caster, fearAuras.empty() ? sWorld->getIntConfig(CONFIG_CREATURE_FAMILY_FLEE_DELAY) : 0); // caster == nullptr processed in MoveFleeing
18317
18318 if (GetTypeId() == TYPEID_PLAYER)
18319 {
18320 sScriptMgr->AnticheatSetSkipOnePacketForASH(ToPlayer(), true);
18321 }
18322 }
18323 else
18324 {
18325 if (IsAlive())
18326 {
18327 if (GetMotionMaster()->GetMotionSlotType(MOTION_SLOT_CONTROLLED) == FLEEING_MOTION_TYPE)
18328 {
18330 StopMoving();
18331 }
18332
18333 if (GetVictim())
18335 }
18336 }
18337
18338 // xinef: block / allow control to real mover (eg. charmer)
18339 if (GetTypeId() == TYPEID_PLAYER)
18340 {
18341 if (m_movedByPlayer)
18342 m_movedByPlayer->ToPlayer()->SetClientControl(this, !apply); // verified
18343 //else
18344 // ToPlayer()->SetClientControl(this, !apply);
18345 }
18346}
@ CONFIG_CREATURE_FAMILY_FLEE_DELAY
Definition: IWorld.h:278
@ FLEEING_MOTION_TYPE
Definition: MotionMaster.h:47
void MoveFleeing(Unit *enemy, uint32 time=0)
Definition: MotionMaster.cpp:657
Unit * getAttackerForHelper() const
Definition: Unit.h:1366

◆ SetFeatherFall()

bool Unit::SetFeatherFall ( bool  enable,
bool  packetOnly = false 
)
virtual

Reimplemented in Player, and Creature.

20734{
20736 return false;
20737
20738 if (enable)
20740 else
20742
20743 return true;
20744}
@ MOVEMENTFLAG_FALLING_SLOW
Definition: Unit.h:581

◆ SetFullHealth()

void Unit::SetFullHealth ( )
inline
1453{ SetHealth(GetMaxHealth()); }

◆ SetHealth()

void Unit::SetHealth ( uint32  val)
15336{
15337 if (getDeathState() == JUST_DIED)
15338 val = 0;
15339 else if (GetTypeId() == TYPEID_PLAYER && getDeathState() == DEAD)
15340 val = 1;
15341 else
15342 {
15343 uint32 maxHealth = GetMaxHealth();
15344 if (maxHealth < val)
15345 val = maxHealth;
15346 }
15347
15348 float prevHealthPct = GetHealthPct();
15349
15351
15352 // mobs that are now or were below 30% need to update their speed
15353 if (GetTypeId() == TYPEID_UNIT && (prevHealthPct < 30.0 || HealthBelowPct(30)))
15354 {
15355 UpdateSpeed(MOVE_RUN, false);
15356 }
15357
15358 // group update
15359 if (GetTypeId() == TYPEID_PLAYER)
15360 {
15361 Player* player = ToPlayer();
15362 if (player->NeedSendSpectatorData())
15364
15365 if (player->GetGroup())
15367 }
15368 else if (Pet* pet = ToCreature()->ToPet())
15369 {
15370 if (pet->isControlled())
15371 {
15372 if (Unit* owner = GetOwner())
15373 if (Player* player = owner->ToPlayer())
15374 {
15375 if (player->NeedSendSpectatorData() && pet->GetCreatureTemplate()->family)
15376 ArenaSpectator::SendCommand_UInt32Value(player->FindMap(), player->GetGUID(), "PHP", (uint32)pet->GetHealthPct());
15377
15378 if (player->GetGroup())
15380 }
15381 }
15382 }
15383}
@ GROUP_UPDATE_FLAG_CUR_HP
Definition: Group.h:100
@ GROUP_UPDATE_FLAG_PET_CUR_HP
Definition: Group.h:112
bool NeedSendSpectatorData() const
Definition: Player.cpp:15090
void SetGroupUpdateFlag(uint32 flag)
Definition: Player.h:2423
float GetHealthPct() const
Definition: Unit.h:1446
void SendCommand_UInt32Value(T *o, ObjectGuid targetGUID, const char *prefix, uint32 t)
Definition: ArenaSpectator.h:62

◆ SetHover()

bool Unit::SetHover ( bool  enable,
bool  packetOnly = false,
bool  updateAnimationTier = true 
)
virtual

Reimplemented in Creature, and Player.

20756{
20758 return false;
20759
20760 float hoverHeight = GetFloatValue(UNIT_FIELD_HOVERHEIGHT);
20761
20762 if (enable)
20763 {
20765 if (hoverHeight && GetPositionZ() - GetFloorZ() < hoverHeight)
20766 UpdateHeight(GetPositionZ() + hoverHeight);
20767 }
20768 else
20769 {
20771 if (hoverHeight && (!isDying() || GetTypeId() != TYPEID_UNIT))
20772 {
20773 float newZ = std::max<float>(GetFloorZ(), GetPositionZ() - hoverHeight);
20775 UpdateHeight(newZ);
20776 }
20777 SendMovementFlagUpdate(); // pussywizard: needed for falling after death (instead of falling onto air at hover height)
20778 }
20779
20780 return true;
20781}
void UpdateHeight(float newZ)
Only server-side height update, does not broadcast to client.
Definition: Unit.cpp:20077
void SendMovementFlagUpdate(bool self=false)
Definition: Unit.cpp:16790
void UpdateAllowedPositionZ(float x, float y, float &z, float *groundZ=nullptr) const
Definition: Object.cpp:1554
float GetFloorZ() const
Definition: Object.cpp:3047

◆ SetImmuneToAll()

void Unit::SetImmuneToAll ( bool  apply,
bool  keepCombat = false 
)
inline
1675{ SetImmuneToPC(apply, keepCombat); SetImmuneToNPC(apply, keepCombat); }
void SetImmuneToNPC(bool apply, bool keepCombat=false)
Definition: Unit.cpp:13520

◆ SetImmuneToNPC()

void Unit::SetImmuneToNPC ( bool  apply,
bool  keepCombat = false 
)
13521{
13522 (void)keepCombat;
13523 if (apply)
13525 else
13527}

◆ SetImmuneToPC()

void Unit::SetImmuneToPC ( bool  apply,
bool  keepCombat = false 
)
13512{
13513 (void)keepCombat;
13514 if (apply)
13516 else
13518}

◆ SetInCombatState()

void Unit::SetInCombatState ( bool  PvP,
Unit enemy = nullptr,
uint32  duration = 0 
)
13628{
13629 // only alive units can be in combat
13630 if (!IsAlive())
13631 return;
13632
13633 if (PvP)
13634 m_CombatTimer = std::max<uint32>(GetCombatTimer(), std::max<uint32>(5500, duration));
13635 else if (duration)
13636 m_CombatTimer = std::max<uint32>(GetCombatTimer(), duration);
13637
13639 return;
13640
13641 // xinef: if we somehow engage in combat (scripts, dunno) with player, remove this flag so he can fight back
13643 SetImmuneToPC(false); // unit has engaged in combat, remove immunity so players can fight back
13644
13645 if (IsInCombat())
13646 return;
13647
13649
13650 if (Creature* creature = ToCreature())
13651 {
13652 // Set home position at place of engaging combat for escorted creatures
13653 if ((IsAIEnabled && creature->AI()->IsEscorted()) ||
13654 GetMotionMaster()->GetCurrentMovementGeneratorType() == WAYPOINT_MOTION_TYPE ||
13655 GetMotionMaster()->GetCurrentMovementGeneratorType() == ESCORT_MOTION_TYPE)
13656 creature->SetHomePosition(GetPositionX(), GetPositionY(), GetPositionZ(), GetOrientation());
13657
13658 if (enemy)
13659 {
13660 if (IsAIEnabled)
13661 creature->AI()->EnterCombat(enemy);
13662
13663 if (creature->GetFormation())
13664 creature->GetFormation()->MemberEngagingTarget(creature, enemy);
13665
13666 sScriptMgr->OnUnitEnterCombat(creature, enemy);
13667 }
13668
13669 creature->RefreshSwimmingFlag();
13670
13671 if (IsPet())
13672 {
13673 UpdateSpeed(MOVE_RUN, true);
13674 UpdateSpeed(MOVE_SWIM, true);
13675 UpdateSpeed(MOVE_FLIGHT, true);
13676 }
13677
13678 if (!(creature->GetCreatureTemplate()->type_flags & CREATURE_TYPE_FLAG_ALLOW_MOUNTED_COMBAT))
13679 Dismount();
13680 if (!IsStandState()) // pussywizard: already done in CombatStart(target, initialAggro) for the target, but when aggro'ing from MoveInLOS CombatStart is not called!
13682 }
13683
13684 for (Unit::ControlSet::iterator itr = m_Controlled.begin(); itr != m_Controlled.end();)
13685 {
13686 Unit* controlled = *itr;
13687 ++itr;
13688
13689 // Xinef: Dont set combat for passive units, they will evade in next update...
13690 if (controlled->GetTypeId() == TYPEID_UNIT && controlled->ToCreature()->HasReactState(REACT_PASSIVE))
13691 continue;
13692
13693 controlled->SetInCombatState(PvP, enemy, duration);
13694 }
13695
13696 if (Player* player = this->ToPlayer())
13697 {
13698 sScriptMgr->OnPlayerEnterCombat(player, enemy);
13699 }
13700}
@ ESCORT_MOTION_TYPE
Definition: MotionMaster.h:55
@ WAYPOINT_MOTION_TYPE
Definition: MotionMaster.h:39
@ CREATURE_TYPE_NON_COMBAT_PET
Definition: SharedDefines.h:2611
@ CREATURE_TYPE_FLAG_ALLOW_MOUNTED_COMBAT
Definition: SharedDefines.h:2678
@ MOVE_FLIGHT
Definition: Unit.h:384
@ MOVE_SWIM
Definition: Unit.h:381
bool HasReactState(ReactStates state) const
Definition: Creature.h:90
uint32 GetCombatTimer() const
Definition: Unit.h:1695
void SetInCombatState(bool PvP, Unit *enemy=nullptr, uint32 duration=0)
Definition: Unit.cpp:13627
bool IsStandState() const
Definition: Unit.cpp:16806

◆ SetInCombatWith()

void Unit::SetInCombatWith ( Unit enemy,
uint32  duration = 0 
)
13486{
13487 // Xinef: Dont allow to start combat with triggers
13488 if (enemy->GetTypeId() == TYPEID_UNIT && enemy->ToCreature()->IsTrigger())
13489 return;
13490
13491 Unit* eOwner = enemy->GetCharmerOrOwnerOrSelf();
13492 if (eOwner->IsPvP() || eOwner->IsFFAPvP())
13493 {
13494 SetInCombatState(true, enemy, duration);
13495 return;
13496 }
13497
13498 // check for duel
13499 if (eOwner->GetTypeId() == TYPEID_PLAYER && eOwner->ToPlayer()->duel)
13500 {
13501 Unit const* myOwner = GetCharmerOrOwnerOrSelf();
13502 if (((Player const*)eOwner)->duel->Opponent == myOwner)
13503 {
13504 SetInCombatState(true, enemy, duration);
13505 return;
13506 }
13507 }
13508 SetInCombatState(false, enemy, duration);
13509}

◆ SetInFront()

void Unit::SetInFront ( WorldObject const *  target)
20614{
20616 SetOrientation(GetAngle(target));
20617}
@ UNIT_STATE_CANNOT_TURN
Definition: Unit.h:369
void SetOrientation(float orientation)
Definition: Position.h:112

◆ SetInstantCast()

void Unit::SetInstantCast ( bool  set)
inline
2431{ _instantCast = set; }

◆ SetLastDamagedTargetGuid()

void Unit::SetLastDamagedTargetGuid ( ObjectGuid const &  guid)
inline
1569{ _lastDamagedTargetGuid = guid; }

◆ SetLastExtraAttackSpell()

void Unit::SetLastExtraAttackSpell ( uint32  spellId)
inline
1566{ _lastExtraAttackSpell = spellId; }

◆ SetLastManaUse()

void Unit::SetLastManaUse ( uint32  spellCastTime)
inline
2212{ m_lastManaUse = spellCastTime; }

◆ SetLevel()

void Unit::SetLevel ( uint8  lvl,
bool  showLevelChange = true 
)
15318{
15320
15321 // Xinef: unmark field bit update
15322 if (!showLevelChange)
15324
15325 // group update
15326 if (GetTypeId() == TYPEID_PLAYER && ToPlayer()->GetGroup())
15328
15329 if (GetTypeId() == TYPEID_PLAYER)
15330 {
15331 sCharacterCache->UpdateCharacterLevel(GetGUID(), lvl);
15332 }
15333}
#define sCharacterCache
Definition: CharacterCache.h:83
@ GROUP_UPDATE_FLAG_LEVEL
Definition: Group.h:105
void UnsetBit(uint32 index)
Definition: UpdateMask.h:47

◆ SetMaxHealth()

void Unit::SetMaxHealth ( uint32  val)
15386{
15387 if (!val)
15388 val = 1;
15389
15390 uint32 health = GetHealth();
15392
15393 // group update
15394 if (GetTypeId() == TYPEID_PLAYER)
15395 {
15396 Player* player = ToPlayer();
15397 if (player->NeedSendSpectatorData())
15399
15400 if (player->GetGroup())
15402 }
15403 else if (Pet* pet = ToCreature()->ToPet())
15404 {
15405 if (pet->isControlled())
15406 {
15407 if (Unit* owner = GetOwner())
15408 if (Player* player = owner->ToPlayer())
15409 {
15410 if (player->NeedSendSpectatorData() && pet->GetCreatureTemplate()->family)
15411 ArenaSpectator::SendCommand_UInt32Value(player->FindMap(), player->GetGUID(), "PHP", (uint32)pet->GetHealthPct());
15412
15413 if (player->GetGroup())
15415 }
15416 }
15417 }
15418
15419 if (val < health)
15420 SetHealth(val);
15421}
@ GROUP_UPDATE_FLAG_MAX_HP
Definition: Group.h:101
@ GROUP_UPDATE_FLAG_PET_MAX_HP
Definition: Group.h:113

◆ SetMaxPower()

void Unit::SetMaxPower ( Powers  power,
uint32  val 
)
15469{
15470 uint32 cur_power = GetPower(power);
15471 SetStatInt32Value(static_cast<uint16>(UNIT_FIELD_MAXPOWER1) + power, val);
15472
15473 // group update
15474 if (GetTypeId() == TYPEID_PLAYER)
15475 {
15476 Player* player = ToPlayer();
15477 if (getPowerType() == power && player->NeedSendSpectatorData())
15478 ArenaSpectator::SendCommand_UInt32Value(FindMap(), GetGUID(), "MPW", power == POWER_RAGE || power == POWER_RUNIC_POWER ? val / 10 : val);
15479
15480 if (player->GetGroup())
15482 }
15483 else if (Pet* pet = ToCreature()->ToPet())
15484 {
15485 if (pet->isControlled())
15486 {
15487 Unit* owner = GetOwner();
15488 if (owner && (owner->GetTypeId() == TYPEID_PLAYER) && owner->ToPlayer()->GetGroup())
15490 }
15491 }
15492
15493 if (val < cur_power)
15494 SetPower(power, val);
15495}
@ GROUP_UPDATE_FLAG_PET_MAX_POWER
Definition: Group.h:116
@ GROUP_UPDATE_FLAG_MAX_POWER
Definition: Group.h:104
void SetStatInt32Value(uint16 index, int32 value)
Definition: Object.cpp:798

◆ SetMinion()

void Unit::SetMinion ( Minion minion,
bool  apply 
)
10629{
10630 LOG_DEBUG("entities.unit", "SetMinion {} for {}, apply {}", minion->GetEntry(), GetEntry(), apply);
10631
10632 if (apply)
10633 {
10634 if (minion->GetOwnerGUID())
10635 {
10636 LOG_FATAL("entities.unit", "SetMinion: Minion {} is not the minion of owner {}", minion->GetEntry(), GetEntry());
10637 return;
10638 }
10639
10640 minion->SetOwnerGUID(GetGUID());
10641
10642 m_Controlled.insert(minion);
10643
10644 if (GetTypeId() == TYPEID_PLAYER)
10645 {
10646 minion->m_ControlledByPlayer = true;
10648 }
10649
10650 // Can only have one pet. If a new one is summoned, dismiss the old one.
10651 if (minion->IsGuardianPet())
10652 {
10653 if (Guardian* oldPet = GetGuardianPet())
10654 {
10655 if (oldPet != minion && (oldPet->IsPet() || minion->IsPet() || oldPet->GetEntry() != minion->GetEntry()))
10656 {
10657 // remove existing minion pet
10658 if (Pet* oldPetAsPet = oldPet->ToPet())
10659 {
10660 oldPetAsPet->Remove(PET_SAVE_NOT_IN_SLOT);
10661 }
10662 else
10663 {
10664 oldPet->UnSummon();
10665 }
10666
10667 SetPetGUID(minion->GetGUID());
10669 }
10670 }
10671 else
10672 {
10673 SetPetGUID(minion->GetGUID());
10675 }
10676 }
10677
10679 {
10681 }
10682
10683 if (minion->m_Properties && minion->m_Properties->Type == SUMMON_TYPE_MINIPET)
10684 {
10685 SetCritterGUID(minion->GetGUID());
10686 }
10687
10688 // PvP, FFAPvP
10690
10691 // FIXME: hack, speed must be set only at follow
10692 if (GetTypeId() == TYPEID_PLAYER && minion->IsPet())
10693 for (uint8 i = 0; i < MAX_MOVE_TYPE; ++i)
10694 minion->SetSpeed(UnitMoveType(i), m_speed_rate[i], true);
10695
10696 // Ghoul pets have energy instead of mana (is anywhere better place for this code?)
10697 if (minion->IsPetGhoul() || minion->GetEntry() == 24207 /*ENTRY_ARMY_OF_THE_DEAD*/)
10698 minion->setPowerType(POWER_ENERGY);
10699
10700 if (GetTypeId() == TYPEID_PLAYER)
10701 {
10702 // Send infinity cooldown - client does that automatically but after relog cooldown needs to be set again
10703 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(minion->GetUInt32Value(UNIT_CREATED_BY_SPELL));
10704
10705 if (spellInfo && spellInfo->IsCooldownStartedOnEvent())
10706 ToPlayer()->AddSpellAndCategoryCooldowns(spellInfo, 0, nullptr, true);
10707 }
10708 }
10709 else
10710 {
10711 if (minion->GetOwnerGUID() != GetGUID())
10712 {
10713 LOG_FATAL("entities.unit", "SetMinion: Minion {} is not the minion of owner {}", minion->GetEntry(), GetEntry());
10714 return;
10715 }
10716
10717 m_Controlled.erase(minion);
10718
10719 if (minion->m_Properties && minion->m_Properties->Type == SUMMON_TYPE_MINIPET)
10720 {
10721 if (GetCritterGUID() == minion->GetGUID())
10723 }
10724
10725 if (minion->IsGuardianPet())
10726 {
10727 if (GetPetGUID() == minion->GetGUID())
10729 }
10730 else if (minion->IsTotem())
10731 {
10732 // All summoned by totem minions must disappear when it is removed.
10733 if (SpellInfo const* spInfo = sSpellMgr->GetSpellInfo(minion->ToTotem()->GetSpell()))
10734 {
10735 for (int i = 0; i < MAX_SPELL_EFFECTS; ++i)
10736 {
10737 if (spInfo->Effects[i].Effect != SPELL_EFFECT_SUMMON)
10738 continue;
10739
10740 RemoveAllMinionsByEntry(spInfo->Effects[i].MiscValue);
10741 }
10742 }
10743 }
10744
10745 if (GetTypeId() == TYPEID_PLAYER)
10746 {
10747 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(minion->GetUInt32Value(UNIT_CREATED_BY_SPELL));
10748 // Remove infinity cooldown
10749 if (spellInfo && spellInfo->IsCooldownStartedOnEvent())
10750 ToPlayer()->SendCooldownEvent(spellInfo);
10751
10752 // xinef: clear spell book
10753 if (m_Controlled.empty())
10755 }
10756
10757 //if (minion->HasUnitTypeMask(UNIT_MASK_GUARDIAN))
10758 {
10760 {
10761 // Check if there is another minion
10762 for (ControlSet::iterator itr = m_Controlled.begin(); itr != m_Controlled.end(); ++itr)
10763 {
10764 // do not use this check, creature do not have charm guid
10765 //if (GetCharmGUID() == (*itr)->GetGUID())
10766 if (GetGUID() == (*itr)->GetCharmerGUID())
10767 continue;
10768
10769 //ASSERT((*itr)->GetOwnerGUID() == GetGUID());
10770 if ((*itr)->GetOwnerGUID() != GetGUID())
10771 {
10772 OutDebugInfo();
10773 (*itr)->OutDebugInfo();
10774 ABORT();
10775 }
10776 ASSERT((*itr)->GetTypeId() == TYPEID_UNIT);
10777
10778 if (!(*itr)->HasUnitTypeMask(UNIT_MASK_CONTROLABLE_GUARDIAN))
10779 continue;
10780
10781 if (AddGuidValue(UNIT_FIELD_SUMMON, (*itr)->GetGUID()))
10782 {
10783 // show another pet bar if there is no charm bar
10784 if (GetTypeId() == TYPEID_PLAYER && !GetCharmGUID())
10785 {
10786 if ((*itr)->IsPet())
10788 else
10790 }
10791 }
10792 break;
10793 }
10794 }
10795 }
10796 }
10797}
@ PET_SAVE_NOT_IN_SLOT
Definition: PetDefines.h:45
@ SPELL_EFFECT_SUMMON
Definition: SharedDefines.h:778
@ SUMMON_TYPE_MINIPET
Definition: SharedDefines.h:3271
UnitMoveType
Definition: Unit.h:377
bool IsGuardianPet() const
Definition: TemporarySummon.cpp:370
bool IsPetGhoul() const
Definition: TemporarySummon.h:79
void PetSpellInitialize()
Definition: Player.cpp:9331
const SummonPropertiesEntry *const m_Properties
Definition: TemporarySummon.h:60
uint32 GetSpell(uint8 slot=0) const
Definition: Totem.h:46
void OutDebugInfo() const
Definition: Unit.cpp:20238
ObjectGuid GetCritterGUID() const
Definition: Unit.h:1823
void SetOwnerGUID(ObjectGuid owner)
Definition: Unit.cpp:10521
void SetSpeed(UnitMoveType mtype, float rate, bool forced=false)
Definition: Unit.cpp:14301
void SetCritterGUID(ObjectGuid guid)
Definition: Unit.h:1822
void setPowerType(Powers power)
Definition: Unit.cpp:9940
void RemoveAllMinionsByEntry(uint32 entry)
Definition: Unit.cpp:10811
uint32 Type
Definition: DBCStructure.h:1875

◆ SetMinionGUID()

void Unit::SetMinionGUID ( ObjectGuid  guid)
inline

◆ SetModelVisible()

void Unit::SetModelVisible ( bool  on)
14128{
14129 if (on)
14130 RemoveAurasDueToSpell(24401);
14131 else
14132 CastSpell(this, 24401, true);
14133}

◆ SetModifierValue()

void Unit::SetModifierValue ( UnitMods  unitMod,
UnitModifierType  modifierType,
float  value 
)
inline
2095{ m_auraModifiersGroup[unitMod][modifierType] = value; }

◆ SetNativeDisplayId()

void Unit::SetNativeDisplayId ( uint32  modelId)
inline

◆ SetNpcFlag()

void Unit::SetNpcFlag ( NPCFlags  flags)
inline
1644{ SetFlag(UNIT_NPC_FLAGS, flags); }

◆ SetOwnerGUID()

void Unit::SetOwnerGUID ( ObjectGuid  owner)
10522{
10523 if (GetOwnerGUID() == owner)
10524 return;
10525
10527 if (!owner)
10528 return;
10529
10530 m_applyResilience = !IsVehicle() && owner.IsPlayer();
10531
10532 // Update owner dependent fields
10533 Player* player = ObjectAccessor::GetPlayer(*this, owner);
10534 if (!player || !player->HaveAtClient(this)) // if player cannot see this unit yet, he will receive needed data with create object
10535 return;
10536
10538
10539 UpdateData udata;
10540 WorldPacket packet;
10541 BuildValuesUpdateBlockForPlayer(&udata, player);
10542 udata.BuildPacket(&packet);
10543 player->SendDirectMessage(&packet);
10544
10546}
void RemoveFieldNotifyFlag(uint16 flag)
Definition: Object.h:189
void BuildValuesUpdateBlockForPlayer(UpdateData *data, Player *target) const
Definition: Object.cpp:257
void SetFieldNotifyFlag(uint16 flag)
Definition: Object.h:188
bool HaveAtClient(WorldObject const *u) const
Definition: Player.h:2333
Definition: UpdateData.h:52
bool BuildPacket(WorldPacket *packet)
Definition: UpdateData.cpp:105

◆ SetPetGUID()

void Unit::SetPetGUID ( ObjectGuid  guid)
inline
1820{ m_SummonSlot[SUMMON_SLOT_PET] = guid; }

◆ SetPhaseMask()

void Unit::SetPhaseMask ( uint32  newPhaseMask,
bool  update 
)
overridevirtual

Reimplemented from WorldObject.

19082{
19083 if (newPhaseMask == GetPhaseMask())
19084 return;
19085
19086 if (IsInWorld())
19087 {
19088 // xinef: to comment, bellow line should be removed
19089 // pussywizard: goign to other phase (valithria, algalon) should not remove such auras
19090 //RemoveNotOwnSingleTargetAuras(newPhaseMask, true); // we can lost access to caster or target
19091
19092 if (!sScriptMgr->CanSetPhaseMask(this, newPhaseMask, update))
19093 return;
19094
19095 // modify hostile references for new phasemask, some special cases deal with hostile references themselves
19096 if (GetTypeId() == TYPEID_UNIT || (!ToPlayer()->IsGameMaster() && !ToPlayer()->GetSession()->PlayerLogout()))
19097 {
19098 HostileRefMgr& refMgr = getHostileRefMgr();
19099 HostileReference* ref = refMgr.getFirst();
19100
19101 while (ref)
19102 {
19103 if (Unit* unit = ref->GetSource()->GetOwner())
19104 if (Creature* creature = unit->ToCreature())
19105 refMgr.setOnlineOfflineState(creature, creature->InSamePhase(newPhaseMask));
19106
19107 ref = ref->next();
19108 }
19109
19110 // modify threat lists for new phasemask
19111 if (GetTypeId() != TYPEID_PLAYER)
19112 {
19115
19116 // merge expects sorted lists
19117 threatList.sort();
19118 offlineThreatList.sort();
19119 threatList.merge(offlineThreatList);
19120
19121 for (ThreatContainer::StorageType::const_iterator itr = threatList.begin(); itr != threatList.end(); ++itr)
19122 if (Unit* unit = (*itr)->getTarget())
19123 unit->getHostileRefMgr().setOnlineOfflineState(ToCreature(), unit->InSamePhase(newPhaseMask));
19124 }
19125 }
19126 }
19127
19128 WorldObject::SetPhaseMask(newPhaseMask, false);
19129
19130 if (!IsInWorld())
19131 {
19132 return;
19133 }
19134
19135 for (ControlSet::const_iterator itr = m_Controlled.begin(); itr != m_Controlled.end(); )
19136 {
19137 Unit* controlled = *itr;
19138 ++itr;
19139 if (controlled->GetTypeId() == TYPEID_UNIT)
19140 {
19141 controlled->SetPhaseMask(newPhaseMask, true);
19142 }
19143 }
19144
19145 for (uint8 i = 0; i < MAX_SUMMON_SLOT; ++i)
19146 {
19147 if (m_SummonSlot[i])
19148 {
19149 if (Creature* summon = GetMap()->GetCreature(m_SummonSlot[i]))
19150 {
19151 summon->SetPhaseMask(newPhaseMask, true);
19152 }
19153 }
19154 }
19155
19156 if (update)
19157 {
19159 }
19160}
Definition: HostileRefMgr.h:32
void setOnlineOfflineState(bool isOnline)
Definition: HostileRefMgr.cpp:98
HostileReference * getFirst()
Definition: HostileRefMgr.h:60
HostileReference * next()
Definition: ThreatMgr.h:116
FROM * GetSource() const
Definition: Reference.h:97
ThreatContainer::StorageType const & GetOfflineThreatList() const
Definition: ThreatMgr.h:272
Unit * GetOwner() const
Definition: ThreatMgr.h:234
void SetPhaseMask(uint32 newPhaseMask, bool update) override
Definition: Unit.cpp:19081
virtual void SetPhaseMask(uint32 newPhaseMask, bool update)
Definition: Object.cpp:2819
uint32 GetPhaseMask() const
Definition: Object.h:434

◆ SetPower()

void Unit::SetPower ( Powers  power,
uint32  val,
bool  withPowerUpdate = true 
)
15424{
15425 if (GetPower(power) == val)
15426 return;
15427
15428 uint32 maxPower = GetMaxPower(power);
15429 if (maxPower < val)
15430 val = maxPower;
15431
15432 SetStatInt32Value(static_cast<uint16>(UNIT_FIELD_POWER1) + power, val);
15433
15434 if (withPowerUpdate)
15435 {
15437 data << GetPackGUID();
15438 data << uint8(power);
15439 data << uint32(val);
15441 }
15442
15443 // group update
15444 if (GetTypeId() == TYPEID_PLAYER)
15445 {
15446 Player* player = ToPlayer();
15447 if (getPowerType() == power && player->NeedSendSpectatorData())
15448 ArenaSpectator::SendCommand_UInt32Value(FindMap(), GetGUID(), "CPW", power == POWER_RAGE || power == POWER_RUNIC_POWER ? val / 10 : val);
15449
15450 if (player->GetGroup())
15452 }
15453 else if (Pet* pet = ToCreature()->ToPet())
15454 {
15455 if (pet->isControlled())
15456 {
15457 Unit* owner = GetOwner();
15458 if (owner && (owner->GetTypeId() == TYPEID_PLAYER) && owner->ToPlayer()->GetGroup())
15460 }
15461
15462 // Update the pet's character sheet with happiness damage bonus
15463 if (pet->getPetType() == HUNTER_PET && power == POWER_HAPPINESS)
15464 pet->UpdateDamagePhysical(BASE_ATTACK);
15465 }
15466}
@ GROUP_UPDATE_FLAG_PET_CUR_POWER
Definition: Group.h:115
@ GROUP_UPDATE_FLAG_CUR_POWER
Definition: Group.h:103
@ SMSG_POWER_UPDATE
Definition: Opcodes.h:1182

◆ setPowerType()

void Unit::setPowerType ( Powers  power)
9941{
9942 SetByteValue(UNIT_FIELD_BYTES_0, 3, new_powertype);
9943
9944 if (GetTypeId() == TYPEID_PLAYER)
9945 {
9946 if (ToPlayer()->GetGroup())
9948 }
9949 else if (Pet* pet = ToCreature()->ToPet())
9950 {
9951 if (pet->isControlled())
9952 {
9953 Unit* owner = GetOwner();
9954 if (owner && (owner->GetTypeId() == TYPEID_PLAYER) && owner->ToPlayer()->GetGroup())
9956 }
9957 }
9958
9959 float powerMultiplier = 1.0f;
9960 if (!IsPet())
9961 if (Creature* creature = ToCreature())
9962 powerMultiplier = creature->GetCreatureTemplate()->ModMana;
9963
9964 switch (new_powertype)
9965 {
9966 default:
9967 case POWER_MANA:
9968 break;
9969 case POWER_RAGE:
9970 SetMaxPower(POWER_RAGE, uint32(std::ceil(GetCreatePowers(POWER_RAGE) * powerMultiplier)));
9971 SetPower(POWER_RAGE, 0);
9972 break;
9973 case POWER_FOCUS:
9974 SetMaxPower(POWER_FOCUS, uint32(std::ceil(GetCreatePowers(POWER_FOCUS) * powerMultiplier)));
9975 SetPower(POWER_FOCUS, uint32(std::ceil(GetCreatePowers(POWER_FOCUS) * powerMultiplier)));
9976 break;
9977 case POWER_ENERGY:
9978 SetMaxPower(POWER_ENERGY, uint32(std::ceil(GetCreatePowers(POWER_ENERGY) * powerMultiplier)));
9979 break;
9980 case POWER_HAPPINESS:
9981 SetMaxPower(POWER_HAPPINESS, uint32(std::ceil(GetCreatePowers(POWER_HAPPINESS) * powerMultiplier)));
9982 SetPower(POWER_HAPPINESS, uint32(std::ceil(GetCreatePowers(POWER_HAPPINESS) * powerMultiplier)));
9983 break;
9984 }
9985
9986 if (Player const* player = ToPlayer())
9987 if (player->NeedSendSpectatorData())
9988 {
9989 ArenaSpectator::SendCommand_UInt32Value(FindMap(), GetGUID(), "PWT", new_powertype);
9990 ArenaSpectator::SendCommand_UInt32Value(FindMap(), GetGUID(), "MPW", new_powertype == POWER_RAGE || new_powertype == POWER_RUNIC_POWER ? GetMaxPower(new_powertype) / 10 : GetMaxPower(new_powertype));
9991 ArenaSpectator::SendCommand_UInt32Value(FindMap(), GetGUID(), "CPW", new_powertype == POWER_RAGE || new_powertype == POWER_RUNIC_POWER ? GetPower(new_powertype) / 10 : GetPower(new_powertype));
9992 }
9993}
@ GROUP_UPDATE_FLAG_POWER_TYPE
Definition: Group.h:102
@ GROUP_UPDATE_FLAG_PET_POWER_TYPE
Definition: Group.h:114
void SetMaxPower(Powers power, uint32 val)
Definition: Unit.cpp:15468

◆ SetPvP()

void Unit::SetPvP ( bool  state)
inline
1518 {
1519 if (state)
1521 else
1523 }
void SetByteFlag(uint16 index, uint8 offset, uint8 newFlag)
Definition: Object.cpp:911

◆ setRace()

void Unit::setRace ( uint8  race)
21036{
21037 if (GetTypeId() == TYPEID_PLAYER)
21038 m_race = race;
21039}

◆ SetRedirectThreat()

void Unit::SetRedirectThreat ( ObjectGuid  guid,
uint32  pct 
)
inline
2339{ _redirectThreatInfo.Set(guid, pct); }
void Set(ObjectGuid guid, uint32 pct)
Definition: Unit.h:956

◆ SetResistance()

void Unit::SetResistance ( SpellSchools  school,
int32  val 
)
inline
1435{ SetStatInt32Value(static_cast<uint16>(UNIT_FIELD_RESISTANCES) + school, val); }

◆ SetResistanceBuffMods()

void Unit::SetResistanceBuffMods ( SpellSchools  school,
bool  positive,
float  val 
)
inline
2023{ SetFloatValue(positive ? static_cast<uint16>(UNIT_FIELD_RESISTANCEBUFFMODSPOSITIVE) + school : static_cast<uint16>(UNIT_FIELD_RESISTANCEBUFFMODSNEGATIVE) + + school, val); }

◆ SetRooted()

void Unit::SetRooted ( bool  apply,
bool  isStun = false 
)
protected
18223{
18224 if (apply)
18225 {
18226 if (m_rootTimes > 0) // blizzard internal check?
18227 m_rootTimes++;
18228
18229 // MOVEMENTFLAG_ROOT cannot be used in conjunction with MOVEMENTFLAG_MASK_MOVING (tested 3.3.5a)
18230 // this will freeze clients. That's why we remove MOVEMENTFLAG_MASK_MOVING before
18231 // setting MOVEMENTFLAG_ROOT
18233
18234 if (IsFalling())
18235 {
18237 }
18238 else
18239 {
18241 }
18242
18243 // Creature specific
18244 if (GetTypeId() != TYPEID_PLAYER)
18245 {
18246 if (isStun && movespline->Finalized())
18247 {
18249 }
18250 else
18251 {
18252 StopMoving();
18253 }
18254 }
18255
18256 if (m_movedByPlayer)
18257 {
18258 WorldPacket data(SMSG_FORCE_MOVE_ROOT, GetPackGUID().size() + 4);
18259 data << GetPackGUID();
18260 data << m_rootTimes;
18262 }
18263 else
18264 {
18266 data << GetPackGUID();
18267 SendMessageToSet(&data, true);
18268 }
18269 }
18270 else
18271 {
18273
18274 if (!HasUnitState(UNIT_STATE_STUNNED)) // prevent moving if it also has stun effect
18275 {
18276 if (m_movedByPlayer)
18277 {
18279 data << GetPackGUID();
18280 data << m_rootTimes;
18282 }
18283 else
18284 {
18286 data << GetPackGUID();
18287 SendMessageToSet(&data, true);
18288 }
18289 }
18290 }
18291}
@ MOVEMENTFLAG_PENDING_ROOT
Definition: Unit.h:572
bool Finalized() const
Definition: MoveSpline.h:116
void StopMovingOnCurrentPos()
Definition: Unit.cpp:16775
@ SMSG_FORCE_MOVE_UNROOT
Definition: Opcodes.h:264
@ SMSG_FORCE_MOVE_ROOT
Definition: Opcodes.h:262
@ SMSG_SPLINE_MOVE_ROOT
Definition: Opcodes.h:824

◆ SetShapeshiftForm()

void Unit::SetShapeshiftForm ( ShapeshiftForm  form)
inline
2070 {
2072 }

◆ SetSheath()

virtual void Unit::SetSheath ( SheathState  sheathed)
inlinevirtual

Reimplemented in Player.

1490{ SetByteValue(UNIT_FIELD_BYTES_2, 0, sheathed); }

◆ SetSpeed()

void Unit::SetSpeed ( UnitMoveType  mtype,
float  rate,
bool  forced = false 
)
14302{
14303 if (rate < 0)
14304 rate = 0.0f;
14305
14306 // Update speed only on change
14307 if (m_speed_rate[mtype] == rate)
14308 return;
14309
14310 m_speed_rate[mtype] = rate;
14311
14313
14314 WorldPacket data;
14315 if (!forced)
14316 {
14317 switch (mtype)
14318 {
14319 case MOVE_WALK:
14320 data.Initialize(MSG_MOVE_SET_WALK_SPEED, 8 + 4 + 2 + 4 + 4 + 4 + 4 + 4 + 4 + 4);
14321 break;
14322 case MOVE_RUN:
14323 data.Initialize(MSG_MOVE_SET_RUN_SPEED, 8 + 4 + 2 + 4 + 4 + 4 + 4 + 4 + 4 + 4);
14324 break;
14325 case MOVE_RUN_BACK:
14326 data.Initialize(MSG_MOVE_SET_RUN_BACK_SPEED, 8 + 4 + 2 + 4 + 4 + 4 + 4 + 4 + 4 + 4);
14327 break;
14328 case MOVE_SWIM:
14329 data.Initialize(MSG_MOVE_SET_SWIM_SPEED, 8 + 4 + 2 + 4 + 4 + 4 + 4 + 4 + 4 + 4);
14330 break;
14331 case MOVE_SWIM_BACK:
14332 data.Initialize(MSG_MOVE_SET_SWIM_BACK_SPEED, 8 + 4 + 2 + 4 + 4 + 4 + 4 + 4 + 4 + 4);
14333 break;
14334 case MOVE_TURN_RATE:
14335 data.Initialize(MSG_MOVE_SET_TURN_RATE, 8 + 4 + 2 + 4 + 4 + 4 + 4 + 4 + 4 + 4);
14336 break;
14337 case MOVE_FLIGHT:
14338 data.Initialize(MSG_MOVE_SET_FLIGHT_SPEED, 8 + 4 + 2 + 4 + 4 + 4 + 4 + 4 + 4 + 4);
14339 break;
14340 case MOVE_FLIGHT_BACK:
14341 data.Initialize(MSG_MOVE_SET_FLIGHT_BACK_SPEED, 8 + 4 + 2 + 4 + 4 + 4 + 4 + 4 + 4 + 4);
14342 break;
14343 case MOVE_PITCH_RATE:
14344 data.Initialize(MSG_MOVE_SET_PITCH_RATE, 8 + 4 + 2 + 4 + 4 + 4 + 4 + 4 + 4 + 4);
14345 break;
14346 default:
14347 LOG_ERROR("entities.unit", "Unit::SetSpeed: Unsupported move type ({}), data not sent to client.", mtype);
14348 return;
14349 }
14350
14351 data << GetPackGUID();
14352 BuildMovementPacket(&data);
14353 data << float(GetSpeed(mtype));
14354 SendMessageToSet(&data, true);
14355 }
14356 else
14357 {
14358 if (GetTypeId() == TYPEID_PLAYER)
14359 {
14360 // register forced speed changes for WorldSession::HandleForceSpeedChangeAck
14361 // and do it only for real sent packets and use run for run/mounted as client expected
14362 ++ToPlayer()->m_forced_speed_changes[mtype];
14363
14364 // Xinef: update speed of pet also
14365 if (!IsInCombat())
14366 {
14367 Unit* pet = ToPlayer()->GetPet();
14368 if (!pet)
14369 pet = GetCharm();
14370
14371 // xinef: do not affect vehicles and possesed pets
14372 if (pet && (pet->HasUnitFlag(UNIT_FLAG_POSSESSED) || pet->IsVehicle()))
14373 pet = nullptr;
14374
14376 pet->UpdateSpeed(mtype, forced);
14377 if (Unit* critter = ObjectAccessor::GetUnit(*this, GetCritterGUID()))
14378 critter->UpdateSpeed(mtype, forced);
14379 }
14380 ToPlayer()->SetCanTeleport(true);
14381 }
14382
14383 switch (mtype)
14384 {
14385 case MOVE_WALK:
14387 break;
14388 case MOVE_RUN:
14390 break;
14391 case MOVE_RUN_BACK:
14393 break;
14394 case MOVE_SWIM:
14396 break;
14397 case MOVE_SWIM_BACK:
14399 break;
14400 case MOVE_TURN_RATE:
14402 break;
14403 case MOVE_FLIGHT:
14405 break;
14406 case MOVE_FLIGHT_BACK:
14408 break;
14409 case MOVE_PITCH_RATE:
14411 break;
14412 default:
14413 LOG_ERROR("entities.unit", "Unit::SetSpeed: Unsupported move type ({}), data not sent to client.", mtype);
14414 return;
14415 }
14416 data << GetPackGUID();
14417 data << (uint32)0; // moveEvent, NUM_PMOVE_EVTS = 0x39
14418 if (mtype == MOVE_RUN)
14419 data << uint8(0); // new 2.1.0
14420 data << float(GetSpeed(mtype));
14421 SendMessageToSet(&data, true);
14422 }
14423}
@ FOLLOW_MOTION_TYPE
Definition: MotionMaster.h:52
@ MOVE_TURN_RATE
Definition: Unit.h:383
@ MOVE_FLIGHT_BACK
Definition: Unit.h:385
@ MOVE_SWIM_BACK
Definition: Unit.h:382
@ MOVE_PITCH_RATE
Definition: Unit.h:386
@ MOVE_RUN_BACK
Definition: Unit.h:380
@ MOVE_WALK
Definition: Unit.h:378
MovementGeneratorType GetCurrentMovementGeneratorType() const
Definition: MotionMaster.cpp:817
void SetCanTeleport(bool value)
Definition: Player.h:2447
uint8 m_forced_speed_changes[MAX_MOVE_TYPE]
Definition: Player.h:2349
float GetSpeed(UnitMoveType mtype) const
Definition: Unit.cpp:14296
void propagateSpeedChange()
-------—End of Pet responses methods-------—
Definition: Unit.h:2304
@ SMSG_FORCE_TURN_RATE_CHANGE
Definition: Opcodes.h:764
@ MSG_MOVE_SET_SWIM_BACK_SPEED
Definition: Opcodes.h:243
@ MSG_MOVE_SET_TURN_RATE
Definition: Opcodes.h:246
@ SMSG_FORCE_WALK_SPEED_CHANGE
Definition: Opcodes.h:760
@ SMSG_FORCE_FLIGHT_BACK_SPEED_CHANGE
Definition: Opcodes.h:929
@ MSG_MOVE_SET_PITCH_RATE
Definition: Opcodes.h:1145
@ SMSG_FORCE_RUN_SPEED_CHANGE
Definition: Opcodes.h:256
@ SMSG_FORCE_SWIM_BACK_SPEED_CHANGE
Definition: Opcodes.h:762
@ SMSG_FORCE_RUN_BACK_SPEED_CHANGE
Definition: Opcodes.h:258
@ SMSG_FORCE_FLIGHT_SPEED_CHANGE
Definition: Opcodes.h:927
@ SMSG_FORCE_SWIM_SPEED_CHANGE
Definition: Opcodes.h:260
@ MSG_MOVE_SET_RUN_SPEED
Definition: Opcodes.h:235
@ MSG_MOVE_SET_FLIGHT_SPEED
Definition: Opcodes.h:924
@ MSG_MOVE_SET_WALK_SPEED
Definition: Opcodes.h:239
@ MSG_MOVE_SET_SWIM_SPEED
Definition: Opcodes.h:241
@ MSG_MOVE_SET_FLIGHT_BACK_SPEED
Definition: Opcodes.h:926
@ SMSG_FORCE_PITCH_RATE_CHANGE
Definition: Opcodes.h:1146
@ MSG_MOVE_SET_RUN_BACK_SPEED
Definition: Opcodes.h:237

◆ SetSpeedRate()

void Unit::SetSpeedRate ( UnitMoveType  mtype,
float  rate 
)
inline
2245{ m_speed_rate[mtype] = rate; }

◆ SetStandFlags()

void Unit::SetStandFlags ( uint8  flags)
inline

◆ SetStandState()

void Unit::SetStandState ( uint8  state)
16813{
16815
16816 if (IsStandState())
16818
16819 if (GetTypeId() == TYPEID_PLAYER)
16820 {
16822 data << (uint8)state;
16823 ToPlayer()->GetSession()->SendPacket(&data);
16824 }
16825}
@ UNIT_BYTES_1_OFFSET_STAND_STATE
Definition: Unit.h:44
@ SMSG_STANDSTATE_UPDATE
Definition: Opcodes.h:699

◆ SetStat()

void Unit::SetStat ( Stats  stat,
int32  val 
)
inline
1429{ SetStatInt32Value(static_cast<uint16>(UNIT_FIELD_STAT0) + stat, val); }

◆ SetStunned()

void Unit::SetStunned ( bool  apply)
protected
18180{
18181 if (apply)
18182 {
18183 SetTarget();
18185
18186 if (GetTypeId() == TYPEID_PLAYER)
18187 {
18189 }
18190
18191 SetRooted(true, true);
18192
18193 CastStop();
18194 }
18195 else
18196 {
18197 if (IsAlive() && GetVictim())
18199
18200 if (GetTypeId() == TYPEID_UNIT)
18201 {
18202 // don't remove UNIT_FLAG_STUNNED for pet when owner is mounted (disabled pet's interface)
18203 Unit* owner = GetOwner();
18204 if (!owner || owner->GetTypeId() != TYPEID_PLAYER || !owner->ToPlayer()->IsMounted())
18206
18207 // Xinef: same for charmed npcs
18208 owner = GetCharmer();
18209 if (!owner || owner->GetTypeId() != TYPEID_PLAYER || !owner->ToPlayer()->IsMounted())
18211 }
18212 else
18214
18215 if (!HasUnitState(UNIT_STATE_ROOT)) // prevent moving if it also has root effect
18216 {
18217 SetRooted(false, true);
18218 }
18219 }
18220}

◆ SetSwim()

bool Unit::SetSwim ( bool  enable)
virtual

Reimplemented in Creature.

20675{
20677 return false;
20678
20679 if (enable)
20680 {
20683 }
20684 else
20685 {
20688 }
20689
20690 return true;
20691}

◆ SetTarget()

virtual void Unit::SetTarget ( ObjectGuid  = ObjectGuid::Empty)
pure virtual

Implemented in Creature, and Player.

◆ setTransForm()

void Unit::setTransForm ( uint32  spellid)
inline
2168{ m_transform = spellid;}

◆ SetUnitFlag()

void Unit::SetUnitFlag ( UnitFlags  flags)
inline
1479{ SetFlag(UNIT_FIELD_FLAGS, flags); }

◆ SetUnitFlag2()

void Unit::SetUnitFlag2 ( UnitFlags2  flags)
inline
1485{ SetFlag(UNIT_FIELD_FLAGS_2, flags); }

◆ SetUnitMovementFlags()

void Unit::SetUnitMovementFlags ( uint32  f)
inline
2271{ m_movementInfo.flags = f; }

◆ SetVisible()

void Unit::SetVisible ( bool  x)
14118{
14119 if (!x)
14121 else
14123
14125}
@ SEC_GAMEMASTER
Definition: Common.h:68

◆ SetVisibleAura()

void Unit::SetVisibleAura ( uint8  slot,
AuraApplication aur 
)
inline
2156{ m_visibleAuras[slot] = aur; UpdateAuraForGroup(slot);}

◆ SetWalk()

bool Unit::SetWalk ( bool  enable)
virtual

Reimplemented in Creature.

20643{
20644 if (enable == IsWalking())
20645 return false;
20646
20647 if (enable)
20649 else
20651
20653 return true;
20654}
bool IsWalking() const
Definition: Unit.h:2374

◆ SetWaterWalking()

bool Unit::SetWaterWalking ( bool  enable,
bool  packetOnly = false 
)
virtual

Reimplemented in Player, and Creature.

20712{
20714 return false;
20715
20716 if (enable)
20718 else
20720
20721 return true;
20722}
@ MOVEMENTFLAG_WATERWALKING
Definition: Unit.h:580

◆ SpellBaseDamageBonusDone()

int32 Unit::SpellBaseDamageBonusDone ( SpellSchoolMask  schoolMask)
11849{
11850 int32 DoneAdvertisedBenefit = 0;
11851
11853 for (AuraEffectList::const_iterator i = mDamageDone.begin(); i != mDamageDone.end(); ++i)
11854 if (((*i)->GetMiscValue() & schoolMask) != 0 &&
11855 (*i)->GetSpellInfo()->EquippedItemClass == -1 &&
11856 // -1 == any item class (not wand then)
11857 (*i)->GetSpellInfo()->EquippedItemInventoryTypeMask == 0)
11858 // 0 == any inventory type (not wand then)
11859 DoneAdvertisedBenefit += (*i)->GetAmount();
11860
11861 if (GetTypeId() == TYPEID_PLAYER)
11862 {
11863 // Base value
11864 DoneAdvertisedBenefit += ToPlayer()->GetBaseSpellPowerBonus();
11865
11866 // Damage bonus from stats
11868 for (AuraEffectList::const_iterator i = mDamageDoneOfStatPercent.begin(); i != mDamageDoneOfStatPercent.end(); ++i)
11869 {
11870 if ((*i)->GetMiscValue() & schoolMask)
11871 {
11872 // stat used stored in miscValueB for this aura
11873 Stats usedStat = Stats((*i)->GetMiscValueB());
11874 DoneAdvertisedBenefit += int32(CalculatePct(GetStat(usedStat), (*i)->GetAmount()));
11875 }
11876 }
11877 // ... and attack power
11879 for (AuraEffectList::const_iterator i = mDamageDonebyAP.begin(); i != mDamageDonebyAP.end(); ++i)
11880 if ((*i)->GetMiscValue() & schoolMask)
11881 DoneAdvertisedBenefit += int32(CalculatePct(GetTotalAttackPowerValue(BASE_ATTACK), (*i)->GetAmount()));
11882 }
11883 return DoneAdvertisedBenefit;
11884}
@ SPELL_AURA_MOD_SPELL_DAMAGE_OF_ATTACK_POWER
Definition: SpellAuraDefines.h:300
@ SPELL_AURA_MOD_SPELL_DAMAGE_OF_STAT_PERCENT
Definition: SpellAuraDefines.h:237
@ SPELL_AURA_MOD_DAMAGE_DONE
Definition: SpellAuraDefines.h:76
uint32 GetBaseSpellPowerBonus()
Definition: Player.h:1920

◆ SpellBaseDamageBonusTaken()

int32 Unit::SpellBaseDamageBonusTaken ( SpellSchoolMask  schoolMask,
bool  isDoT = false 
)
11887{
11888 int32 TakenAdvertisedBenefit = 0;
11889
11891 for (AuraEffectList::const_iterator i = mDamageTaken.begin(); i != mDamageTaken.end(); ++i)
11892 if (((*i)->GetMiscValue() & schoolMask) != 0)
11893 {
11894 // Xinef: if we have DoT damage type and aura has charges, check if it affects DoTs
11895 // Xinef: required for hemorrhage & rupture / garrote
11896 if (isDoT && (*i)->GetBase()->IsUsingCharges() && !((*i)->GetSpellInfo()->ProcFlags & PROC_FLAG_TAKEN_PERIODIC))
11897 continue;
11898
11899 TakenAdvertisedBenefit += (*i)->GetAmount();
11900 }
11901
11902 return TakenAdvertisedBenefit;
11903}

◆ SpellBaseHealingBonusDone()

int32 Unit::SpellBaseHealingBonusDone ( SpellSchoolMask  schoolMask)
12607{
12608 int32 AdvertisedBenefit = 0;
12609
12611 for (AuraEffectList::const_iterator i = mHealingDone.begin(); i != mHealingDone.end(); ++i)
12612 if (!(*i)->GetMiscValue() || ((*i)->GetMiscValue() & schoolMask) != 0)
12613 AdvertisedBenefit += (*i)->GetAmount();
12614
12615 // Healing bonus of spirit, intellect and strength
12616 if (GetTypeId() == TYPEID_PLAYER)
12617 {
12618 // Base value
12619 AdvertisedBenefit += ToPlayer()->GetBaseSpellPowerBonus();
12620
12621 // Healing bonus from stats
12623 for (AuraEffectList::const_iterator i = mHealingDoneOfStatPercent.begin(); i != mHealingDoneOfStatPercent.end(); ++i)
12624 {
12625 // stat used dependent from misc value (stat index)
12626 Stats usedStat = Stats((*i)->GetSpellInfo()->Effects[(*i)->GetEffIndex()].MiscValue);
12627 AdvertisedBenefit += int32(CalculatePct(GetStat(usedStat), (*i)->GetAmount()));
12628 }
12629
12630 // ... and attack power
12632 for (AuraEffectList::const_iterator i = mHealingDonebyAP.begin(); i != mHealingDonebyAP.end(); ++i)
12633 if ((*i)->GetMiscValue() & schoolMask)
12634 AdvertisedBenefit += int32(CalculatePct(GetTotalAttackPowerValue(BASE_ATTACK), (*i)->GetAmount()));
12635 }
12636 return AdvertisedBenefit;
12637}
@ SPELL_AURA_MOD_HEALING_DONE
Definition: SpellAuraDefines.h:198
@ SPELL_AURA_MOD_SPELL_HEALING_OF_STAT_PERCENT
Definition: SpellAuraDefines.h:238
@ SPELL_AURA_MOD_SPELL_HEALING_OF_ATTACK_POWER
Definition: SpellAuraDefines.h:301

◆ SpellBaseHealingBonusTaken()

int32 Unit::SpellBaseHealingBonusTaken ( SpellSchoolMask  schoolMask)
12640{
12641 int32 AdvertisedBenefit = 0;
12642
12644 for (AuraEffectList::const_iterator i = mDamageTaken.begin(); i != mDamageTaken.end(); ++i)
12645 if (((*i)->GetMiscValue() & schoolMask) != 0)
12646 AdvertisedBenefit += (*i)->GetAmount();
12647
12648 return AdvertisedBenefit;
12649}
@ SPELL_AURA_MOD_HEALING
Definition: SpellAuraDefines.h:178

◆ SpellCriticalDamageBonus()

uint32 Unit::SpellCriticalDamageBonus ( Unit const *  caster,
SpellInfo const *  spellProto,
uint32  damage,
Unit const *  victim 
)
static
12193{
12194 // Calculate critical bonus
12195 int32 crit_bonus = damage;
12196 float crit_mod = 0.0f;
12197
12198 switch (spellProto->DmgClass)
12199 {
12200 case SPELL_DAMAGE_CLASS_MELEE: // for melee based spells is 100%
12202 // TODO: write here full calculation for melee/ranged spells
12203 crit_bonus += damage;
12204 break;
12205 default:
12206 crit_bonus += damage / 2; // for spells is 50%
12207 break;
12208 }
12209
12210 if (caster)
12211 {
12212 crit_mod += caster->GetTotalAuraModifierByMiscMask(SPELL_AURA_MOD_CRIT_DAMAGE_BONUS, spellProto->GetSchoolMask());
12213
12214 if (victim)
12215 crit_mod += caster->GetTotalAuraModifierByMiscMask(SPELL_AURA_MOD_CRIT_PERCENT_VERSUS, victim->GetCreatureTypeMask());
12216
12217 if (crit_bonus != 0 && crit_mod != 0.0f)
12218 AddPct(crit_bonus, crit_mod);
12219
12220 crit_bonus -= damage;
12221
12222 // adds additional damage to critBonus (from talents)
12223 if (Player* modOwner = caster->GetSpellModOwner())
12224 modOwner->ApplySpellMod(spellProto->Id, SPELLMOD_CRIT_DAMAGE_BONUS, crit_bonus);
12225
12226 crit_bonus += damage;
12227 }
12228
12229 return crit_bonus;
12230}

◆ SpellCriticalHealingBonus()

uint32 Unit::SpellCriticalHealingBonus ( Unit const *  caster,
SpellInfo const *  spellProto,
uint32  damage,
Unit const *  victim 
)
static
12233{
12234 // Calculate critical bonus
12235 int32 crit_bonus;
12236 switch (spellProto->DmgClass)
12237 {
12238 case SPELL_DAMAGE_CLASS_MELEE: // for melee based spells is 100%
12240 // TODO: write here full calculation for melee/ranged spells
12241 crit_bonus = damage;
12242 break;
12243 default:
12244 crit_bonus = damage / 2; // for spells is 50%
12245 break;
12246 }
12247
12248 if (caster)
12249 {
12250 if (victim)
12251 {
12252 uint32 creatureTypeMask = victim->GetCreatureTypeMask();
12253 crit_bonus = int32(crit_bonus * caster->GetTotalAuraMultiplierByMiscMask(SPELL_AURA_MOD_CRIT_PERCENT_VERSUS, creatureTypeMask));
12254 }
12255
12256 // adds additional damage to critBonus (from talents)
12257 // xinef: used for death knight death coil
12258 if (Player* modOwner = caster->GetSpellModOwner())
12259 modOwner->ApplySpellMod(spellProto->Id, SPELLMOD_CRIT_DAMAGE_BONUS, crit_bonus);
12260 }
12261
12262 if (crit_bonus > 0)
12263 damage += crit_bonus;
12264
12265 if (caster)
12266 damage = int32(float(damage) * caster->GetTotalAuraMultiplier(SPELL_AURA_MOD_CRITICAL_HEALING_AMOUNT));
12267
12268 return damage;
12269}
@ SPELL_AURA_MOD_CRITICAL_HEALING_AMOUNT
Definition: SpellAuraDefines.h:113

◆ SpellDamageBonusDone()

uint32 Unit::SpellDamageBonusDone ( Unit victim,
SpellInfo const *  spellProto,
uint32  pdamage,
DamageEffectType  damagetype,
uint8  effIndex,
float  TotalMod = 0.0f,
uint32  stack = 1 
)
11560{
11561 if (!spellProto || !victim || damagetype == DIRECT_DAMAGE)
11562 return pdamage;
11563
11564 // Some spells don't benefit from done mods
11565 if (spellProto->HasAttribute(SPELL_ATTR3_IGNORE_CASTER_MODIFIERS))
11566 return pdamage;
11567
11568 // For totems get damage bonus from owner
11569 if (GetTypeId() == TYPEID_UNIT)
11570 {
11571 if (IsTotem())
11572 {
11573 if (Unit* owner = GetOwner())
11574 return owner->SpellDamageBonusDone(victim, spellProto, pdamage, damagetype, effIndex, TotalMod, stack);
11575 }
11576 // Dancing Rune Weapon...
11577 else if (GetEntry() == 27893)
11578 {
11579 if (Unit* owner = GetOwner())
11580 return owner->SpellDamageBonusDone(victim, spellProto, pdamage, damagetype, TotalMod, stack) / 2;
11581 }
11582 }
11583
11584 // Done total percent damage auras
11585 float ApCoeffMod = 1.0f;
11586 int32 DoneTotal = 0;
11587 float DoneTotalMod = TotalMod ? TotalMod : SpellPctDamageModsDone(victim, spellProto, damagetype);
11588
11589 // Config : RATE_CREATURE_X_SPELLDAMAGE & Do Not Modify Pet/Guardian/Mind Controled Damage
11591 DoneTotalMod *= ToCreature()->GetSpellDamageMod(ToCreature()->GetCreatureTemplate()->rank);
11592
11593 // Some spells don't benefit from pct done mods
11594 if (!spellProto->HasAttribute(SPELL_ATTR6_IGNORE_CASTER_DAMAGE_MODIFIERS))
11595 {
11596 uint32 creatureTypeMask = victim->GetCreatureTypeMask();
11597 // Add flat bonus from spell damage versus
11599 }
11600
11601 // done scripted mod (take it from owner)
11602 Unit* owner = GetOwner() ? GetOwner() : this;
11603 AuraEffectList const& mOverrideClassScript = owner->GetAuraEffectsByType(SPELL_AURA_OVERRIDE_CLASS_SCRIPTS);
11604 for (AuraEffectList::const_iterator i = mOverrideClassScript.begin(); i != mOverrideClassScript.end(); ++i)
11605 {
11606 if (!(*i)->IsAffectedOnSpell(spellProto))
11607 continue;
11608
11609 switch ((*i)->GetMiscValue())
11610 {
11611 case 4418: // Increased Shock Damage
11612 case 4554: // Increased Lightning Damage
11613 case 4555: // Improved Moonfire
11614 case 5142: // Increased Lightning Damage
11615 case 5147: // Improved Consecration / Libram of Resurgence
11616 case 5148: // Idol of the Shooting Star
11617 case 6008: // Increased Lightning Damage
11618 case 8627: // Totem of Hex
11619 {
11620 DoneTotal += (*i)->GetAmount();
11621 break;
11622 }
11623 }
11624 }
11625
11626 // Custom scripted damage
11627 if (spellProto->SpellFamilyName == SPELLFAMILY_DEATHKNIGHT)
11628 {
11629 // Sigil of the Vengeful Heart
11630 if (spellProto->SpellFamilyFlags[0] & 0x2000)
11631 if (AuraEffect* aurEff = GetAuraEffect(64962, EFFECT_1))
11632 AddPct(DoneTotal, aurEff->GetAmount());
11633
11634 // Impurity
11636 AddPct(ApCoeffMod, aurEff->GetAmount());
11637
11638 // Blood Boil - bonus for diseased targets
11639 if (spellProto->SpellFamilyFlags[0] & 0x00040000)
11641 {
11642 DoneTotal += 95;
11643 ApCoeffMod = 1.5835f;
11644 }
11645 }
11646
11647 // Done fixed damage bonus auras
11648 int32 DoneAdvertisedBenefit = SpellBaseDamageBonusDone(spellProto->GetSchoolMask());
11649
11650 // Check for table values
11651 float coeff = spellProto->Effects[effIndex].BonusMultiplier;
11652 SpellBonusEntry const* bonus = sSpellMgr->GetSpellBonusData(spellProto->Id);
11653 if (bonus)
11654 {
11655 if (damagetype == DOT)
11656 {
11657 coeff = bonus->dot_damage;
11658 if (bonus->ap_dot_bonus > 0)
11659 {
11660 WeaponAttackType attType = (spellProto->IsRangedWeaponSpell() && spellProto->DmgClass != SPELL_DAMAGE_CLASS_MELEE) ? RANGED_ATTACK : BASE_ATTACK;
11662 APbonus += GetTotalAttackPowerValue(attType);
11663 DoneTotal += int32(bonus->ap_dot_bonus * stack * ApCoeffMod * APbonus);
11664 }
11665 }
11666 else
11667 {
11668 coeff = bonus->direct_damage;
11669 if (bonus->ap_bonus > 0)
11670 {
11671 WeaponAttackType attType = (spellProto->IsRangedWeaponSpell() && spellProto->DmgClass != SPELL_DAMAGE_CLASS_MELEE) ? RANGED_ATTACK : BASE_ATTACK;
11673 APbonus += GetTotalAttackPowerValue(attType);
11674 DoneTotal += int32(bonus->ap_bonus * stack * ApCoeffMod * APbonus);
11675 }
11676 }
11677 }
11678
11679 // Default calculation
11680 if (coeff && DoneAdvertisedBenefit)
11681 {
11682 float factorMod = CalculateLevelPenalty(spellProto) * stack;
11683
11684 if (Player* modOwner = GetSpellModOwner())
11685 {
11686 coeff *= 100.0f;
11687 modOwner->ApplySpellMod(spellProto->Id, SPELLMOD_BONUS_MULTIPLIER, coeff);
11688 coeff /= 100.0f;
11689 }
11690
11691 DoneTotal += int32(DoneAdvertisedBenefit * coeff * factorMod);
11692 }
11693
11694 float tmpDamage = (float(pdamage) + DoneTotal) * DoneTotalMod;
11695 // apply spellmod to Done damage (flat and pct)
11696 if (Player* modOwner = GetSpellModOwner())
11697 modOwner->ApplySpellMod(spellProto->Id, damagetype == DOT ? SPELLMOD_DOT : SPELLMOD_DAMAGE, tmpDamage);
11698
11699 return uint32(std::max(tmpDamage, 0.0f));
11700}
@ SPELL_ATTR6_IGNORE_CASTER_DAMAGE_MODIFIERS
Definition: SharedDefines.h:605
@ SPELL_AURA_MOD_FLAT_SPELL_DAMAGE_VERSUS
Definition: SpellAuraDefines.h:243
@ SPELLMOD_DOT
Definition: SpellDefines.h:99
@ SPELLMOD_BONUS_MULTIPLIER
Definition: SpellDefines.h:101
float GetSpellDamageMod(int32 Rank)
Definition: Creature.cpp:1564
float SpellPctDamageModsDone(Unit *victim, SpellInfo const *spellProto, DamageEffectType damagetype)
Definition: Unit.cpp:11228
float CalculateLevelPenalty(SpellInfo const *spellProto) const
Definition: Unit.cpp:2990
Definition: SpellMgr.h:317
float ap_dot_bonus
Definition: SpellMgr.h:321
float dot_damage
Definition: SpellMgr.h:319
float ap_bonus
Definition: SpellMgr.h:320
float direct_damage
Definition: SpellMgr.h:318

◆ SpellDamageBonusTaken()

uint32 Unit::SpellDamageBonusTaken ( Unit caster,
SpellInfo const *  spellProto,
uint32  pdamage,
DamageEffectType  damagetype,
uint32  stack = 1 
)
11703{
11704 if (!spellProto || damagetype == DIRECT_DAMAGE)
11705 return pdamage;
11706
11707 int32 TakenTotal = 0;
11708 float TakenTotalMod = 1.0f;
11709
11710 // from positive and negative SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN
11711 // multiplicative bonus, for example Dispersion + Shadowform (0.10*0.85=0.085)
11713 for (AuraEffectList::const_iterator i = mTotalAuraList.begin(); i != mTotalAuraList.end(); ++i)
11714 if (((*i)->GetMiscValue() & spellProto->GetSchoolMask()))
11715 if (spellProto->ValidateAttribute6SpellDamageMods(caster, *i, damagetype == DOT))
11716 AddPct(TakenTotalMod, (*i)->GetAmount());
11717
11718 TakenTotalMod = processDummyAuras(TakenTotalMod);
11719
11720 // From caster spells
11721 if (caster)
11722 {
11724 for (AuraEffectList::const_iterator i = mOwnerTaken.begin(); i != mOwnerTaken.end(); ++i)
11725 if ((*i)->GetCasterGUID() == caster->GetGUID() && (*i)->IsAffectedOnSpell(spellProto))
11726 if (spellProto->ValidateAttribute6SpellDamageMods(caster, *i, damagetype == DOT))
11727 AddPct(TakenTotalMod, (*i)->GetAmount());
11728 }
11729
11730 if (uint32 mechanicMask = spellProto->GetAllEffectsMechanicMask())
11731 {
11732 int32 modifierMax = 0;
11733 int32 modifierMin = 0;
11735 for (AuraEffectList::const_iterator i = auraEffectList.begin(); i != auraEffectList.end(); ++i)
11736 {
11737 if (!spellProto->ValidateAttribute6SpellDamageMods(caster, *i, damagetype == DOT))
11738 continue;
11739
11740 // Only death knight spell with this aura
11741 if ((*i)->GetSpellInfo()->SpellFamilyName == SPELLFAMILY_DEATHKNIGHT)
11742 if (!caster || caster->GetGUID() != (*i)->GetCasterGUID())
11743 continue;
11744
11745 if (mechanicMask & uint32(1 << (*i)->GetMiscValue()))
11746 {
11747 if ((*i)->GetAmount() > 0)
11748 {
11749 if ((*i)->GetAmount() > modifierMax)
11750 modifierMax = (*i)->GetAmount();
11751 }
11752 else if ((*i)->GetAmount() < modifierMin)
11753 modifierMin = (*i)->GetAmount();
11754 }
11755 }
11756
11757 AddPct(TakenTotalMod, modifierMax);
11758 AddPct(TakenTotalMod, modifierMin);
11759 }
11760
11761 int32 TakenAdvertisedBenefit = SpellBaseDamageBonusTaken(spellProto->GetSchoolMask(), damagetype == DOT);
11762
11763 // Check for table values
11764 float coeff = 0;
11765 SpellBonusEntry const* bonus = sSpellMgr->GetSpellBonusData(spellProto->Id);
11766 if (bonus)
11767 coeff = (damagetype == DOT) ? bonus->dot_damage : bonus->direct_damage;
11768
11769 // Default calculation
11770 if (TakenAdvertisedBenefit)
11771 {
11772 if (coeff <= 0.0f)
11773 {
11774 if (caster)
11775 coeff = caster->CalculateDefaultCoefficient(spellProto, damagetype) * int32(stack);
11776 else
11777 coeff = CalculateDefaultCoefficient(spellProto, damagetype) * int32(stack);
11778 }
11779
11780 float factorMod = CalculateLevelPenalty(spellProto) * stack;
11781 TakenTotal += int32(TakenAdvertisedBenefit * coeff * factorMod);
11782 }
11783
11784 // No positive taken bonus, custom attr
11785 if (spellProto->HasAttribute(SPELL_ATTR0_CU_NO_POSITIVE_TAKEN_BONUS) && TakenTotalMod > 1.0f)
11786 {
11787 TakenTotal = 0;
11788 TakenTotalMod = 1.0f;
11789 }
11790
11791 // xinef: sanctified wrath talent
11792 if (caster && TakenTotalMod < 1.0f && caster->HasAuraType(SPELL_AURA_MOD_IGNORE_TARGET_RESIST))
11793 {
11794 float ignoreModifier = 1.0f - TakenTotalMod;
11795 bool addModifier = false;
11797 for (AuraEffectList::const_iterator j = ResIgnoreAuras.begin(); j != ResIgnoreAuras.end(); ++j)
11798 if ((*j)->GetMiscValue() & spellProto->SchoolMask)
11799 {
11800 ApplyPct(ignoreModifier, (*j)->GetAmount());
11801 addModifier = true;
11802 }
11803
11804 if (addModifier)
11805 TakenTotalMod += ignoreModifier;
11806 }
11807
11808 float tmpDamage = (float(pdamage) + TakenTotal) * TakenTotalMod;
11809
11810 return uint32(std::max(tmpDamage, 0.0f));
11811}
float CalculateDefaultCoefficient(SpellInfo const *spellInfo, DamageEffectType damagetype) const
Definition: Unit.cpp:17257

◆ SpellDoneCritChance()

float Unit::SpellDoneCritChance ( Unit const *  ,
SpellInfo const *  spellProto,
SpellSchoolMask  schoolMask,
WeaponAttackType  attackType,
bool  skipEffectCheck 
) const
11906{
11907 // Mobs can't crit with spells.
11908 if (GetTypeId() == TYPEID_UNIT && !GetSpellModOwner())
11909 return -100.0f;
11910
11911 // not critting spell
11912 if (spellProto->HasAttribute(SPELL_ATTR2_CANT_CRIT))
11913 return 0.0f;
11914
11915 // Xinef: check if spell is capable of critting, auras requires special aura to crit so they can be skipped
11916 if (!skipEffectCheck && !spellProto->IsCritCapable())
11917 return 0.0f;
11918
11919 float crit_chance = 0.0f;
11920 switch (spellProto->DmgClass)
11921 {
11923 {
11924 if (schoolMask & SPELL_SCHOOL_MASK_NORMAL)
11925 crit_chance = 0.0f;
11926 // For other schools
11927 else if (GetTypeId() == TYPEID_PLAYER)
11928 crit_chance = GetFloatValue(static_cast<uint16>(PLAYER_SPELL_CRIT_PERCENTAGE1) + GetFirstSchoolInMask(schoolMask));
11929 else
11930 {
11931 crit_chance = (float)m_baseSpellCritChance;
11933 }
11934 break;
11935 }
11938 {
11939 if (GetTypeId() == TYPEID_PLAYER)
11940 {
11941 switch (attackType)
11942 {
11943 case BASE_ATTACK:
11945 break;
11946 case OFF_ATTACK:
11948 break;
11949 case RANGED_ATTACK:
11951 break;
11952 default:
11953 break;
11954 }
11955 }
11956 else
11957 {
11958 crit_chance = 5.0f;
11961 }
11963 break;
11964 }
11965 // values overridden in spellmgr for lifebloom and earth shield
11967 default:
11968 return 0.0f;
11969 }
11970
11971 // percent done
11972 // only players use intelligence for critical chance computations
11973 if (Player* modOwner = GetSpellModOwner())
11974 modOwner->ApplySpellMod(spellProto->Id, SPELLMOD_CRITICAL_CHANCE, crit_chance);
11975
11976 // xinef: can be negative!
11977 return crit_chance;
11978}
@ SPELL_ATTR2_CANT_CRIT
Definition: SharedDefines.h:457
@ SPELL_AURA_MOD_SPELL_CRIT_CHANCE_SCHOOL
Definition: SpellAuraDefines.h:134
@ SPELLMOD_CRITICAL_CHANCE
Definition: SpellDefines.h:84
@ PLAYER_SPELL_CRIT_PERCENTAGE1
Definition: UpdateFields.h:354

◆ SpellHealingBonusDone()

uint32 Unit::SpellHealingBonusDone ( Unit victim,
SpellInfo const *  spellProto,
uint32  healamount,
DamageEffectType  damagetype,
uint8  effIndex,
float  TotalMod = 0.0f,
uint32  stack = 1 
)
12364{
12365 // For totems get healing bonus from owner (statue isn't totem in fact)
12366 if (GetTypeId() == TYPEID_UNIT && IsTotem())
12367 if (Unit* owner = GetOwner())
12368 return owner->SpellHealingBonusDone(victim, spellProto, healamount, damagetype, effIndex, TotalMod, stack);
12369
12370 // No bonus healing for potion spells
12371 if (spellProto->SpellFamilyName == SPELLFAMILY_POTION)
12372 return healamount;
12373
12374 float ApCoeffMod = 1.0f;
12375 float DoneTotalMod = TotalMod ? TotalMod : SpellPctHealingModsDone(victim, spellProto, damagetype);
12376 int32 DoneTotal = 0;
12377
12378 // done scripted mod (take it from owner)
12379 Unit* owner = GetOwner() ? GetOwner() : this;
12380 AuraEffectList const& mOverrideClassScript = owner->GetAuraEffectsByType(SPELL_AURA_OVERRIDE_CLASS_SCRIPTS);
12381 for (AuraEffectList::const_iterator i = mOverrideClassScript.begin(); i != mOverrideClassScript.end(); ++i)
12382 {
12383 if (!(*i)->IsAffectedOnSpell(spellProto))
12384 continue;
12385 switch ((*i)->GetMiscValue())
12386 {
12387 case 4415: // Increased Rejuvenation Healing
12388 case 4953:
12389 DoneTotal += (*i)->GetAmount() / 5; // 5 ticks of Rejuvenation
12390 break;
12391 case 3736: // Hateful Totem of the Third Wind / Increased Lesser Healing Wave / LK Arena (4/5/6) Totem of the Third Wind / Savage Totem of the Third Wind
12392 DoneTotal += (*i)->GetAmount();
12393 break;
12394 }
12395 }
12396
12397 // Done fixed damage bonus auras
12398 int32 DoneAdvertisedBenefit = SpellBaseHealingBonusDone(spellProto->GetSchoolMask());
12399 float coeff = spellProto->Effects[effIndex].BonusMultiplier;
12400
12401 switch (spellProto->SpellFamilyName)
12402 {
12404 // Impurity
12406 AddPct(ApCoeffMod, aurEff->GetAmount());
12407
12408 break;
12409 }
12410
12411 // Check for table values
12412 SpellBonusEntry const* bonus = sSpellMgr->GetSpellBonusData(spellProto->Id);
12413 if(bonus)
12414 {
12415 if (damagetype == DOT)
12416 {
12417 coeff = bonus->dot_damage;
12418 if (bonus->ap_dot_bonus > 0)
12419 DoneTotal += int32(bonus->ap_dot_bonus * ApCoeffMod * stack * GetTotalAttackPowerValue(
12420 (spellProto->IsRangedWeaponSpell() && spellProto->DmgClass != SPELL_DAMAGE_CLASS_MELEE) ? RANGED_ATTACK : BASE_ATTACK));
12421 }
12422 else
12423 {
12424 coeff = bonus->direct_damage;
12425 if (bonus->ap_bonus > 0)
12426 DoneTotal += int32(bonus->ap_bonus * ApCoeffMod * stack * GetTotalAttackPowerValue(
12427 (spellProto->IsRangedWeaponSpell() && spellProto->DmgClass != SPELL_DAMAGE_CLASS_MELEE) ? RANGED_ATTACK : BASE_ATTACK));
12428 }
12429 }
12430 else
12431 {
12432 // No bonus healing for SPELL_DAMAGE_CLASS_NONE class spells by default
12433 if (spellProto->DmgClass == SPELL_DAMAGE_CLASS_NONE)
12434 return healamount;
12435 }
12436
12437 // Default calculation
12438 if (DoneAdvertisedBenefit)
12439 {
12440 float factorMod = CalculateLevelPenalty(spellProto) * stack;
12441 if (Player* modOwner = GetSpellModOwner())
12442 {
12443 coeff *= 100.0f;
12444 modOwner->ApplySpellMod(spellProto->Id, SPELLMOD_BONUS_MULTIPLIER, coeff);
12445 coeff /= 100.0f;
12446 }
12447 DoneTotal += int32(DoneAdvertisedBenefit * coeff * factorMod);
12448 }
12449
12450 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
12451 {
12452 switch (spellProto->Effects[i].ApplyAuraName)
12453 {
12454 // Bonus healing does not apply to these spells
12457 DoneTotal = 0;
12458 break;
12459 }
12460 if (spellProto->Effects[i].Effect == SPELL_EFFECT_HEALTH_LEECH)
12461 DoneTotal = 0;
12462 }
12463
12464 // use float as more appropriate for negative values and percent applying
12465 float heal = float(int32(healamount) + DoneTotal) * DoneTotalMod;
12466 // apply spellmod to Done amount
12467
12468 if (Player* modOwner = GetSpellModOwner())
12469 modOwner->ApplySpellMod(spellProto->Id, damagetype == DOT ? SPELLMOD_DOT : SPELLMOD_DAMAGE, heal);
12470
12471 return uint32(std::max(heal, 0.0f));
12472}
@ SPELL_AURA_PERIODIC_HEALTH_FUNNEL
Definition: SpellAuraDefines.h:125
int32 SpellBaseHealingBonusDone(SpellSchoolMask schoolMask)
Definition: Unit.cpp:12606
float SpellPctHealingModsDone(Unit *victim, SpellInfo const *spellProto, DamageEffectType damagetype)
Definition: Unit.cpp:12271

◆ SpellHealingBonusTaken()

uint32 Unit::SpellHealingBonusTaken ( Unit caster,
SpellInfo const *  spellProto,
uint32  healamount,
DamageEffectType  damagetype,
uint32  stack = 1 
)
12475{
12476 float TakenTotalMod = 1.0f;
12477 float minval = 0.0f;
12478
12479 // Healing taken percent
12480 if (!sScriptMgr->OnSpellHealingBonusTakenNegativeModifiers(this, caster, spellProto, minval))
12481 {
12483 }
12484
12485 if (minval)
12486 AddPct(TakenTotalMod, minval);
12487
12489 if (maxval)
12490 AddPct(TakenTotalMod, maxval);
12491
12492 // Tenacity increase healing % taken
12493 if (AuraEffect const* Tenacity = GetAuraEffect(58549, 0))
12494 AddPct(TakenTotalMod, Tenacity->GetAmount());
12495
12496 // Healing Done
12497 int32 TakenTotal = 0;
12498
12499 // Taken fixed damage bonus auras
12500 int32 TakenAdvertisedBenefit = SpellBaseHealingBonusTaken(spellProto->GetSchoolMask());
12501
12502 // Nourish cast, glyph of nourish
12503 if (spellProto->SpellFamilyName == SPELLFAMILY_DRUID && spellProto->SpellFamilyFlags[1] & 0x2000000 && caster)
12504 {
12505 bool any = false;
12506 bool hasglyph = caster->GetAuraEffectDummy(62971);
12508 for (AuraEffectList::const_iterator i = auras.begin(); i != auras.end(); ++i)
12509 {
12510 if (((*i)->GetCasterGUID() == caster->GetGUID()))
12511 {
12512 SpellInfo const* spell = (*i)->GetSpellInfo();
12513 // Rejuvenation, Regrowth, Lifebloom, or Wild Growth
12514 if (!any && spell->SpellFamilyFlags.HasFlag(0x50, 0x4000010, 0))
12515 {
12516 TakenTotalMod *= 1.2f;
12517 any = true;
12518 }
12519
12520 if (hasglyph)
12521 TakenTotalMod += 0.06f;
12522 }
12523 }
12524 }
12525
12526 if (damagetype == DOT)
12527 {
12528 // Healing over time taken percent
12529 float minval_hot = float(GetMaxNegativeAuraModifier(SPELL_AURA_MOD_HOT_PCT));
12530 if (minval_hot)
12531 AddPct(TakenTotalMod, minval_hot);
12532
12533 float maxval_hot = float(GetMaxPositiveAuraModifier(SPELL_AURA_MOD_HOT_PCT));
12534 if (maxval_hot)
12535 AddPct(TakenTotalMod, maxval_hot);
12536 }
12537
12538 // Check for table values
12539 SpellBonusEntry const* bonus = sSpellMgr->GetSpellBonusData(spellProto->Id);
12540 float coeff = 0;
12541 float factorMod = 1.0f;
12542 if (bonus)
12543 coeff = (damagetype == DOT) ? bonus->dot_damage : bonus->direct_damage;
12544 else
12545 {
12546 // No bonus healing for SPELL_DAMAGE_CLASS_NONE class spells by default
12547 if (spellProto->DmgClass == SPELL_DAMAGE_CLASS_NONE)
12548 {
12549 healamount = uint32(std::max((float(healamount) * TakenTotalMod), 0.0f));
12550 return healamount;
12551 }
12552 }
12553
12554 // Default calculation
12555 if (TakenAdvertisedBenefit)
12556 {
12557 float TakenCoeff = 0.0f;
12558 if (coeff <= 0)
12559 coeff = CalculateDefaultCoefficient(spellProto, damagetype) * int32(stack) * 1.88f; // As wowwiki says: C = (Cast Time / 3.5) * 1.88 (for healing spells)
12560
12561 factorMod *= CalculateLevelPenalty(spellProto) * int32(stack);
12562 if (Player* modOwner = GetSpellModOwner())
12563 {
12564 coeff *= 100.0f;
12565 modOwner->ApplySpellMod(spellProto->Id, SPELLMOD_BONUS_MULTIPLIER, coeff);
12566 coeff /= 100.0f;
12567 }
12568
12569 TakenTotal += int32(TakenAdvertisedBenefit * (coeff > 0 ? coeff : TakenCoeff) * factorMod);
12570 }
12571
12572 if (caster)
12573 {
12575 for (AuraEffectList::const_iterator i = mHealingGet.begin(); i != mHealingGet.end(); ++i)
12576 if (caster->GetGUID() == (*i)->GetCasterGUID() && (*i)->IsAffectedOnSpell(spellProto))
12577 AddPct(TakenTotalMod, (*i)->GetAmount());
12578 }
12579
12580 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
12581 {
12582 switch (spellProto->Effects[i].ApplyAuraName)
12583 {
12584 // Bonus healing does not apply to these spells
12587 TakenTotal = 0;
12588 break;
12589 }
12590 if (spellProto->Effects[i].Effect == SPELL_EFFECT_HEALTH_LEECH)
12591 TakenTotal = 0;
12592 }
12593
12594 // No positive taken bonus, custom attr
12595 if ((spellProto->HasAttribute(SPELL_ATTR6_IGNORE_HEALTH_MODIFIERS) || spellProto->HasAttribute(SPELL_ATTR0_CU_NO_POSITIVE_TAKEN_BONUS)) && TakenTotalMod > 1.0f)
12596 {
12597 TakenTotal = 0;
12598 TakenTotalMod = 1.0f;
12599 }
12600
12601 float heal = float(int32(healamount) + TakenTotal) * TakenTotalMod;
12602
12603 return uint32(std::max(heal, 0.0f));
12604}
@ SPELL_ATTR6_IGNORE_HEALTH_MODIFIERS
Definition: SharedDefines.h:603
@ SPELL_AURA_MOD_HEALING_RECEIVED
Definition: SpellAuraDefines.h:346
@ SPELL_AURA_MOD_HEALING_PCT
Definition: SpellAuraDefines.h:181
@ SPELL_AURA_MOD_HOT_PCT
Definition: SpellAuraDefines.h:322
int32 GetMaxPositiveAuraModifier(AuraType auratype)
Definition: Unit.cpp:5835
int32 GetMaxNegativeAuraModifier(AuraType auratype) const
Definition: Unit.cpp:5849
int32 SpellBaseHealingBonusTaken(SpellSchoolMask schoolMask)
Definition: Unit.cpp:12639

◆ SpellHitResult() [1/2]

SpellMissInfo Unit::SpellHitResult ( Unit victim,
Spell const *  spell,
bool  canReflect = false 
)
3477{
3478 SpellInfo const* spellInfo = spell->GetSpellInfo();
3479
3480 // Check for immune
3481 if (victim->IsImmunedToSpell(spellInfo, spell))
3482 {
3483 return SPELL_MISS_IMMUNE;
3484 }
3485
3486 // All positive spells can`t miss
3487 // TODO: client not show miss log for this spells - so need find info for this in dbc and use it!
3488 if ((spellInfo->IsPositive() || spellInfo->HasEffect(SPELL_EFFECT_DISPEL))
3489 && (!IsHostileTo(victim))) // prevent from affecting enemy by "positive" spell
3490 {
3491 return SPELL_MISS_NONE;
3492 }
3493
3494 // Check for immune
3495 // xinef: check for school immunity only
3496 if (victim->IsImmunedToSchool(spell))
3497 {
3498 return SPELL_MISS_IMMUNE;
3499 }
3500
3501 if (this == victim)
3502 {
3503 return SPELL_MISS_NONE;
3504 }
3505
3506 // Return evade for units in evade mode
3507 if (victim->GetTypeId() == TYPEID_UNIT && victim->ToCreature()->IsEvadingAttacks() && !spellInfo->HasAura(SPELL_AURA_CONTROL_VEHICLE) &&
3509 {
3510 return SPELL_MISS_EVADE;
3511 }
3512
3513 // Try victim reflect spell
3514 if (CanReflect)
3515 {
3516 int32 reflectchance = victim->GetTotalAuraModifier(SPELL_AURA_REFLECT_SPELLS);
3517 Unit::AuraEffectList const& mReflectSpellsSchool = victim->GetAuraEffectsByType(SPELL_AURA_REFLECT_SPELLS_SCHOOL);
3518 for (Unit::AuraEffectList::const_iterator i = mReflectSpellsSchool.begin(); i != mReflectSpellsSchool.end(); ++i)
3519 {
3520 if ((*i)->GetMiscValue() & spell->GetSpellSchoolMask())
3521 {
3522 reflectchance += (*i)->GetAmount();
3523 }
3524 }
3525
3526 if (reflectchance > 0 && roll_chance_i(reflectchance))
3527 {
3528 // Start triggers for remove charges if need (trigger only for victim, and mark as active spell)
3529 //ProcDamageAndSpell(victim, PROC_FLAG_NONE, PROC_FLAG_TAKEN_SPELL_MAGIC_DMG_CLASS_NEG, PROC_EX_REFLECT, 1, BASE_ATTACK, spell);
3530 return SPELL_MISS_REFLECT;
3531 }
3532 }
3533
3534 switch (spellInfo->DmgClass)
3535 {
3538 return MeleeSpellHitResult(victim, spellInfo);
3540 {
3541 if (spellInfo->SpellFamilyName)
3542 {
3543 return SPELL_MISS_NONE;
3544 }
3545
3546 // Xinef: apply DAMAGE_CLASS_MAGIC conditions to damaging DAMAGE_CLASS_NONE spells
3547 for (uint8 i = EFFECT_0; i < MAX_SPELL_EFFECTS; ++i)
3548 {
3549 if (spellInfo->Effects[i].Effect && spellInfo->Effects[i].Effect != SPELL_EFFECT_SCHOOL_DAMAGE)
3550 {
3551 if (spellInfo->Effects[i].ApplyAuraName != SPELL_AURA_PERIODIC_DAMAGE)
3552 {
3553 return SPELL_MISS_NONE;
3554 }
3555 }
3556 }
3557 [[fallthrough]];
3558 }
3560 return MagicSpellHitResult(victim, spellInfo);
3561 }
3562
3563 return SPELL_MISS_NONE;
3564}
@ SPELL_EFFECT_DISPEL
Definition: SharedDefines.h:788
@ SPELL_MISS_IMMUNE
Definition: SharedDefines.h:1498
@ SPELL_MISS_EVADE
Definition: SharedDefines.h:1497
@ SPELL_MISS_REFLECT
Definition: SharedDefines.h:1502
@ SPELL_AURA_REFLECT_SPELLS
Definition: SpellAuraDefines.h:91
uint32 DmgClass
Definition: SpellInfo.h:387
SpellMissInfo MagicSpellHitResult(Unit *victim, SpellInfo const *spell)
Definition: Unit.cpp:3269
SpellMissInfo MeleeSpellHitResult(Unit *victim, SpellInfo const *spell)
Definition: Unit.cpp:3096

◆ SpellHitResult() [2/2]

SpellMissInfo Unit::SpellHitResult ( Unit victim,
SpellInfo const *  spell,
bool  canReflect = false 
)
3413{
3414 // Check for immune
3415 if (victim->IsImmunedToSpell(spell))
3416 return SPELL_MISS_IMMUNE;
3417
3418 // All positive spells can`t miss
3419 // TODO: client not show miss log for this spells - so need find info for this in dbc and use it!
3420 if ((spell->IsPositive() || spell->HasEffect(SPELL_EFFECT_DISPEL))
3421 && (!IsHostileTo(victim))) // prevent from affecting enemy by "positive" spell
3422 return SPELL_MISS_NONE;
3423
3424 // Check for immune
3425 // xinef: check for school immunity only
3426 if (victim->IsImmunedToSchool(spell))
3427 return SPELL_MISS_IMMUNE;
3428
3429 if (this == victim)
3430 return SPELL_MISS_NONE;
3431
3432 // Return evade for units in evade mode
3433 if (victim->GetTypeId() == TYPEID_UNIT && victim->ToCreature()->IsEvadingAttacks() && !spell->HasAura(SPELL_AURA_CONTROL_VEHICLE) && !spell->HasAttribute(SPELL_ATTR0_CU_IGNORE_EVADE))
3434 return SPELL_MISS_EVADE;
3435
3436 // Try victim reflect spell
3437 if (CanReflect)
3438 {
3439 int32 reflectchance = victim->GetTotalAuraModifier(SPELL_AURA_REFLECT_SPELLS);
3440 Unit::AuraEffectList const& mReflectSpellsSchool = victim->GetAuraEffectsByType(SPELL_AURA_REFLECT_SPELLS_SCHOOL);
3441 for (Unit::AuraEffectList::const_iterator i = mReflectSpellsSchool.begin(); i != mReflectSpellsSchool.end(); ++i)
3442 if ((*i)->GetMiscValue() & spell->GetSchoolMask())
3443 reflectchance += (*i)->GetAmount();
3444 if (reflectchance > 0 && roll_chance_i(reflectchance))
3445 {
3446 // Start triggers for remove charges if need (trigger only for victim, and mark as active spell)
3447 //ProcDamageAndSpell(victim, PROC_FLAG_NONE, PROC_FLAG_TAKEN_SPELL_MAGIC_DMG_CLASS_NEG, PROC_EX_REFLECT, 1, BASE_ATTACK, spell);
3448 return SPELL_MISS_REFLECT;
3449 }
3450 }
3451
3452 switch (spell->DmgClass)
3453 {
3456 return MeleeSpellHitResult(victim, spell);
3458 {
3459 if (spell->SpellFamilyName)
3460 {
3461 return SPELL_MISS_NONE;
3462 }
3463 // Xinef: apply DAMAGE_CLASS_MAGIC conditions to damaging DAMAGE_CLASS_NONE spells
3464 for (uint8 i = EFFECT_0; i < MAX_SPELL_EFFECTS; ++i)
3465 if (spell->Effects[i].Effect && spell->Effects[i].Effect != SPELL_EFFECT_SCHOOL_DAMAGE)
3466 if (spell->Effects[i].ApplyAuraName != SPELL_AURA_PERIODIC_DAMAGE)
3467 return SPELL_MISS_NONE;
3468 [[fallthrough]];
3469 }
3471 return MagicSpellHitResult(victim, spell);
3472 }
3473 return SPELL_MISS_NONE;
3474}

◆ SpellPctDamageModsDone()

float Unit::SpellPctDamageModsDone ( Unit victim,
SpellInfo const *  spellProto,
DamageEffectType  damagetype 
)
11229{
11230 if (!spellProto || !victim || damagetype == DIRECT_DAMAGE)
11231 return 1.0f;
11232
11233 // Some spells don't benefit from done mods
11234 if (spellProto->HasAttribute(SPELL_ATTR3_IGNORE_CASTER_MODIFIERS))
11235 return 1.0f;
11236
11237 // For totems get damage bonus from owner
11238 if (GetTypeId() == TYPEID_UNIT)
11239 {
11240 if (IsTotem())
11241 {
11242 if (Unit* owner = GetOwner())
11243 return owner->SpellPctDamageModsDone(victim, spellProto, damagetype);
11244 }
11245 // Dancing Rune Weapon...
11246 else if (GetEntry() == 27893)
11247 {
11248 if (Unit* owner = GetOwner())
11249 return owner->SpellPctDamageModsDone(victim, spellProto, damagetype);
11250 }
11251 }
11252
11253 // Done total percent damage auras
11254 float DoneTotalMod = 1.0f;
11255
11257 for (AuraEffectList::const_iterator i = mModDamagePercentDone.begin(); i != mModDamagePercentDone.end(); ++i)
11258 {
11259 // prevent apply mods from weapon specific case to non weapon specific spells (Example: thunder clap and two-handed weapon specialization)
11260 if (spellProto->EquippedItemClass == -1 && (*i)->GetSpellInfo()->EquippedItemClass != -1 &&
11261 !(*i)->GetSpellInfo()->HasAttribute(SPELL_ATTR5_AURA_AFFECTS_NOT_JUST_REQ_EQUIPED_ITEM) && (*i)->GetMiscValue() == SPELL_SCHOOL_MASK_NORMAL)
11262 {
11263 continue;
11264 }
11265
11266 if (!spellProto->ValidateAttribute6SpellDamageMods(this, *i, damagetype == DOT))
11267 continue;
11268
11269 if (!sScriptMgr->IsNeedModSpellDamagePercent(this, *i, DoneTotalMod, spellProto))
11270 continue;
11271
11272 if ((*i)->GetMiscValue() & spellProto->GetSchoolMask())
11273 {
11274 if ((*i)->GetSpellInfo()->EquippedItemClass == -1)
11275 AddPct(DoneTotalMod, (*i)->GetAmount());
11276 else if (!(*i)->GetSpellInfo()->HasAttribute(SPELL_ATTR5_AURA_AFFECTS_NOT_JUST_REQ_EQUIPED_ITEM) && ((*i)->GetSpellInfo()->EquippedItemSubClassMask == 0))
11277 AddPct(DoneTotalMod, (*i)->GetAmount());
11278 else if (ToPlayer() && ToPlayer()->HasItemFitToSpellRequirements((*i)->GetSpellInfo()))
11279 AddPct(DoneTotalMod, (*i)->GetAmount());
11280 }
11281 }
11282
11283 uint32 creatureTypeMask = victim->GetCreatureTypeMask();
11285 for (AuraEffectList::const_iterator i = mDamageDoneVersus.begin(); i != mDamageDoneVersus.end(); ++i)
11286 if ((creatureTypeMask & uint32((*i)->GetMiscValue())) && spellProto->ValidateAttribute6SpellDamageMods(this, *i, damagetype == DOT))
11287 AddPct(DoneTotalMod, (*i)->GetAmount());
11288
11289 // bonus against aurastate
11291 for (AuraEffectList::const_iterator i = mDamageDoneVersusAurastate.begin(); i != mDamageDoneVersusAurastate.end(); ++i)
11292 if (victim->HasAuraState(AuraStateType((*i)->GetMiscValue())) && spellProto->ValidateAttribute6SpellDamageMods(this, *i, damagetype == DOT))
11293 AddPct(DoneTotalMod, (*i)->GetAmount());
11294
11295 // done scripted mod (take it from owner)
11296 Unit* owner = GetOwner() ? GetOwner() : this;
11297 AuraEffectList const& mOverrideClassScript = owner->GetAuraEffectsByType(SPELL_AURA_OVERRIDE_CLASS_SCRIPTS);
11298 for (AuraEffectList::const_iterator i = mOverrideClassScript.begin(); i != mOverrideClassScript.end(); ++i)
11299 {
11300 // Xinef: self cast is ommited (because of Rage of Rivendare)
11301 if (!spellProto->ValidateAttribute6SpellDamageMods(this, *i, damagetype == DOT))
11302 continue;
11303
11304 // xinef: Molten Fury should work on all spells
11305 switch ((*i)->GetMiscValue())
11306 {
11307 case 4920: // Molten Fury
11308 case 4919:
11309 if (victim->HasAuraState(AURA_STATE_HEALTHLESS_35_PERCENT, spellProto, this))
11310 AddPct(DoneTotalMod, (*i)->GetAmount());
11311 break;
11312 }
11313
11314 if (!(*i)->IsAffectedOnSpell(spellProto))
11315 continue;
11316
11317 switch ((*i)->GetMiscValue())
11318 {
11319 case 6917: // Death's Embrace
11320 case 6926:
11321 case 6928:
11322 {
11323 if (victim->HasAuraState(AURA_STATE_HEALTHLESS_35_PERCENT, spellProto, this))
11324 AddPct(DoneTotalMod, (*i)->GetAmount());
11325 break;
11326 }
11327 // Soul Siphon
11328 case 4992:
11329 case 4993:
11330 {
11331 // effect 1 m_amount
11332 int32 maxPercent = (*i)->GetAmount();
11333 // effect 0 m_amount
11334 int32 stepPercent = CalculateSpellDamage(this, (*i)->GetSpellInfo(), 0);
11335 // count affliction effects and calc additional damage in percentage
11336 int32 modPercent = 0;
11337 AuraApplicationMap const& victimAuras = victim->GetAppliedAuras();
11338 for (AuraApplicationMap::const_iterator itr = victimAuras.begin(); itr != victimAuras.end(); ++itr)
11339 {
11340 Aura const* aura = itr->second->GetBase();
11341 SpellInfo const* m_spell = aura->GetSpellInfo();
11342 if (m_spell->SpellFamilyName != SPELLFAMILY_WARLOCK || !(m_spell->SpellFamilyFlags[1] & 0x0004071B || m_spell->SpellFamilyFlags[0] & 0x8044C402))
11343 continue;
11344 modPercent += stepPercent * aura->GetStackAmount();
11345 if (modPercent >= maxPercent)
11346 {
11347 modPercent = maxPercent;
11348 break;
11349 }
11350 }
11351 AddPct(DoneTotalMod, modPercent);
11352 break;
11353 }
11354 case 6916: // Death's Embrace
11355 case 6925:
11356 case 6927:
11357 if (HasAuraState(AURA_STATE_HEALTHLESS_20_PERCENT, spellProto, this))
11358 AddPct(DoneTotalMod, (*i)->GetAmount());
11359 break;
11360 case 5481: // Starfire Bonus
11361 {
11362 if (victim->GetAuraEffect(SPELL_AURA_PERIODIC_DAMAGE, SPELLFAMILY_DRUID, 0x200002, 0, 0))
11363 AddPct(DoneTotalMod, (*i)->GetAmount());
11364 break;
11365 }
11366 // Tundra Stalker
11367 // Merciless Combat
11368 case 7277:
11369 {
11370 // Merciless Combat
11371 if ((*i)->GetSpellInfo()->SpellIconID == 2656)
11372 {
11373 if( (spellProto && spellProto->SpellFamilyFlags[0] & 0x2) || spellProto->SpellFamilyFlags[1] & 0x2 )
11374 if (!victim->HealthAbovePct(35))
11375 AddPct(DoneTotalMod, (*i)->GetAmount());
11376 }
11377 // Tundra Stalker
11378 else
11379 {
11380 // Frost Fever (target debuff)
11381 if (victim->HasAura(55095))
11382 AddPct(DoneTotalMod, (*i)->GetAmount());
11383 break;
11384 }
11385 break;
11386 }
11387 // Rage of Rivendare
11388 case 7293:
11389 {
11391 AddPct(DoneTotalMod, (*i)->GetSpellInfo()->GetRank() * 2.0f);
11392 break;
11393 }
11394 // Twisted Faith
11395 case 7377:
11396 {
11398 AddPct(DoneTotalMod, (*i)->GetAmount());
11399 break;
11400 }
11401 // Marked for Death
11402 case 7598:
11403 case 7599:
11404 case 7600:
11405 case 7601:
11406 case 7602:
11407 {
11408 if (victim->GetAuraEffect(SPELL_AURA_MOD_STALKED, SPELLFAMILY_HUNTER, 0x400, 0, 0))
11409 AddPct(DoneTotalMod, (*i)->GetAmount());
11410 break;
11411 }
11412 // Dirty Deeds
11413 case 6427:
11414 case 6428:
11415 case 6579:
11416 case 6580:
11417 {
11418 if (victim->HasAuraState(AURA_STATE_HEALTHLESS_35_PERCENT, spellProto, this))
11419 {
11420 // effect 0 has expected value but in negative state
11421 int32 bonus = -(*i)->GetBase()->GetEffect(0)->GetAmount();
11422 AddPct(DoneTotalMod, bonus);
11423 }
11424 break;
11425 }
11426 }
11427 }
11428
11429 // Custom scripted damage
11430 switch (spellProto->SpellFamilyName)
11431 {
11432 case SPELLFAMILY_MAGE:
11433 // Ice Lance
11434 if (spellProto->SpellIconID == 186)
11435 {
11436 if (victim->HasAuraState(AURA_STATE_FROZEN, spellProto, this))
11437 {
11438 // Glyph of Ice Lance
11439 if (owner->HasAura(56377) && victim->getLevel() > owner->getLevel())
11440 DoneTotalMod *= 4.0f;
11441 else
11442 DoneTotalMod *= 3.0f;
11443 }
11444 }
11445
11446 // Torment the weak
11447 if (spellProto->SpellFamilyFlags[0] & 0x20600021 || spellProto->SpellFamilyFlags[1] & 0x9000)
11448 if (victim->HasAuraWithMechanic((1 << MECHANIC_SNARE) | (1 << MECHANIC_SLOW_ATTACK)))
11450 AddPct(DoneTotalMod, aurEff->GetAmount());
11451 break;
11452 case SPELLFAMILY_PRIEST:
11453 // Mind Flay
11454 if (spellProto->SpellFamilyFlags[0] & 0x800000)
11455 {
11456 // Glyph of Shadow Word: Pain
11457 if (AuraEffect* aurEff = GetAuraEffect(55687, 0))
11458 // Increase Mind Flay damage if Shadow Word: Pain present on target
11460 AddPct(DoneTotalMod, aurEff->GetAmount());
11461
11462 // Twisted Faith - Mind Flay part
11464 // Increase Mind Flay damage if Shadow Word: Pain present on target
11466 AddPct(DoneTotalMod, aurEff->GetAmount());
11467 }
11468 // Smite
11469 else if (spellProto->SpellFamilyFlags[0] & 0x80)
11470 {
11471 // Glyph of Smite
11472 if (AuraEffect* aurEff = GetAuraEffect(55692, 0))
11473 if (victim->GetAuraEffect(SPELL_AURA_PERIODIC_DAMAGE, SPELLFAMILY_PRIEST, 0x100000, 0, 0, GetGUID()))
11474 AddPct(DoneTotalMod, aurEff->GetAmount());
11475 }
11476 // Shadow Word: Death
11477 else if (spellProto->SpellFamilyFlags[1] & 0x2)
11478 {
11479 // Glyph of Shadow Word: Death
11480 if (AuraEffect* aurEff = GetAuraEffect(55682, 1))
11482 AddPct(DoneTotalMod, aurEff->GetAmount());
11483 }
11484
11485 break;
11487 // Judgement of Vengeance/Judgement of Corruption
11488 if ((spellProto->SpellFamilyFlags[1] & 0x400000) && spellProto->SpellIconID == 2292)
11489 {
11490 // Get stack of Holy Vengeance/Blood Corruption on the target added by caster
11491 uint32 stacks = 0;
11493 for (Unit::AuraEffectList::const_iterator itr = auras.begin(); itr != auras.end(); ++itr)
11494 if (((*itr)->GetId() == 31803 || (*itr)->GetId() == 53742) && (*itr)->GetCasterGUID() == GetGUID())
11495 {
11496 stacks = (*itr)->GetBase()->GetStackAmount();
11497 break;
11498 }
11499 // + 10% for each application of Holy Vengeance/Blood Corruption on the target
11500 if (stacks)
11501 AddPct(DoneTotalMod, 10 * stacks);
11502 }
11503 break;
11504 case SPELLFAMILY_DRUID:
11505 // Thorns
11506 if (spellProto->SpellFamilyFlags[0] & 0x100)
11507 {
11508 // Brambles
11509 if (AuraEffect* aurEff = GetAuraEffectOfRankedSpell(16836, 0))
11510 AddPct(DoneTotalMod, aurEff->GetAmount());
11511 }
11512 break;
11514 // Fire and Brimstone
11515 if (spellProto->SpellFamilyFlags[1] & 0x00020040)
11517 {
11519 for (AuraEffectList::const_iterator i = mDumyAuras.begin(); i != mDumyAuras.end(); ++i)
11520 if ((*i)->GetSpellInfo()->SpellIconID == 3173)
11521 {
11522 AddPct(DoneTotalMod, (*i)->GetAmount());
11523 break;
11524 }
11525 }
11526 // Drain Soul - increased damage for targets under 25 % HP
11527 if (spellProto->SpellFamilyFlags[0] & 0x00004000)
11528 if (!victim->HealthAbovePct(25))
11529 DoneTotalMod *= 4;
11530 // Shadow Bite (15% increase from each dot)
11531 if (spellProto->SpellFamilyFlags[1] & 0x00400000 && IsPet())
11532 if (uint8 count = victim->GetDoTsByCaster(GetOwnerGUID()))
11533 AddPct(DoneTotalMod, 15 * count);
11534 break;
11535 case SPELLFAMILY_HUNTER:
11536 // Steady Shot
11537 if (spellProto->SpellFamilyFlags[1] & 0x1)
11538 if (AuraEffect* aurEff = GetAuraEffect(56826, 0)) // Glyph of Steady Shot
11539 if (victim->GetAuraEffect(SPELL_AURA_PERIODIC_DAMAGE, SPELLFAMILY_HUNTER, 0x00004000, 0, 0, GetGUID()))
11540 AddPct(DoneTotalMod, aurEff->GetAmount());
11541 break;
11543 // Improved Icy Touch
11544 if (spellProto->SpellFamilyFlags[0] & 0x2)
11546 AddPct(DoneTotalMod, aurEff->GetAmount());
11547
11548 // Glacier Rot
11549 if (spellProto->SpellFamilyFlags[0] & 0x2 || spellProto->SpellFamilyFlags[1] & 0x6)
11551 if (victim->GetDiseasesByCaster(owner->GetGUID()) > 0)
11552 AddPct(DoneTotalMod, aurEff->GetAmount());
11553 break;
11554 }
11555
11556 return DoneTotalMod;
11557}
@ MECHANIC_SLOW_ATTACK
Definition: SharedDefines.h:1305
@ AURA_STATE_HEALTHLESS_20_PERCENT
Definition: SharedDefines.h:1265
uint32 GetDiseasesByCaster(ObjectGuid casterGUID, uint8 mode=0)
Definition: Unit.cpp:5721
bool HasAuraWithMechanic(uint32 mechanicMask) const
Definition: Unit.cpp:5692
AuraEffect * GetAuraEffectOfRankedSpell(uint32 spellId, uint8 effIndex, ObjectGuid casterGUID=ObjectGuid::Empty) const
Definition: Unit.cpp:5414
uint32 GetDoTsByCaster(ObjectGuid casterGUID) const
Definition: Unit.cpp:5767

◆ SpellPctHealingModsDone()

float Unit::SpellPctHealingModsDone ( Unit victim,
SpellInfo const *  spellProto,
DamageEffectType  damagetype 
)
12272{
12273 // For totems get healing bonus from owner (statue isn't totem in fact)
12274 if (GetTypeId() == TYPEID_UNIT && IsTotem())
12275 if (Unit* owner = GetOwner())
12276 return owner->SpellPctHealingModsDone(victim, spellProto, damagetype);
12277
12278 // Some spells don't benefit from done mods
12279 if (spellProto->HasAttribute(SPELL_ATTR3_IGNORE_CASTER_MODIFIERS))
12280 return 1.0f;
12281
12282 // xinef: Some spells don't benefit from done mods
12283 if (spellProto->HasAttribute(SPELL_ATTR6_IGNORE_HEALTH_MODIFIERS))
12284 return 1.0f;
12285
12286 // No bonus healing for potion spells
12287 if (spellProto->SpellFamilyName == SPELLFAMILY_POTION)
12288 return 1.0f;
12289
12290 float DoneTotalMod = 1.0f;
12291
12292 // Healing done percent
12294 for (auto const& auraEff : mHealingDonePct)
12295 {
12296 if (!sScriptMgr->IsNeedModHealPercent(this, auraEff, DoneTotalMod, spellProto))
12297 continue;
12298
12299 AddPct(DoneTotalMod, auraEff->GetAmount());
12300 }
12301
12302 // done scripted mod (take it from owner)
12303 Unit* owner = GetOwner() ? GetOwner() : this;
12304 AuraEffectList const& mOverrideClassScript = owner->GetAuraEffectsByType(SPELL_AURA_OVERRIDE_CLASS_SCRIPTS);
12305 for (AuraEffectList::const_iterator i = mOverrideClassScript.begin(); i != mOverrideClassScript.end(); ++i)
12306 {
12307 if (!(*i)->IsAffectedOnSpell(spellProto))
12308 continue;
12309
12310 switch ((*i)->GetMiscValue())
12311 {
12312 case 21: // Test of Faith
12313 case 6935:
12314 case 6918:
12315 if (victim->HealthBelowPct(50))
12316 AddPct(DoneTotalMod, (*i)->GetAmount());
12317 break;
12318 case 7798: // Glyph of Regrowth
12319 {
12321 AddPct(DoneTotalMod, (*i)->GetAmount());
12322 break;
12323 }
12324
12325 case 7871: // Glyph of Lesser Healing Wave
12326 {
12327 // xinef: affected by any earth shield
12328 if (victim->GetAuraEffect(SPELL_AURA_DUMMY, SPELLFAMILY_SHAMAN, 0, 0x00000400, 0))
12329 AddPct(DoneTotalMod, (*i)->GetAmount());
12330 break;
12331 }
12332 default:
12333 break;
12334 }
12335 }
12336
12337 switch (spellProto->SpellFamilyName)
12338 {
12340 // Talents and glyphs for healing stream totem
12341 if (spellProto->Id == 52042)
12342 {
12343 // Glyph of Healing Stream Totem
12344 if (AuraEffect* dummy = owner->GetAuraEffect(55456, EFFECT_0))
12345 AddPct(DoneTotalMod, dummy->GetAmount());
12346
12347 // Healing Stream totem - Restorative Totems
12348 if (AuraEffect* aurEff = GetDummyAuraEffect(SPELLFAMILY_SHAMAN, 338, 1))
12349 AddPct(DoneTotalMod, aurEff->GetAmount());
12350 }
12351 break;
12352 case SPELLFAMILY_PRIEST:
12353 // T9 HEALING 4P, empowered renew instant heal
12354 if (spellProto->Id == 63544)
12355 if (AuraEffect* aurEff = GetAuraEffect(67202, EFFECT_0))
12356 AddPct(DoneTotalMod, aurEff->GetAmount());
12357 break;
12358 }
12359
12360 return DoneTotalMod;
12361}
@ SPELL_AURA_MOD_HEALING_DONE_PERCENT
Definition: SpellAuraDefines.h:199

◆ SpellTakenCritChance()

float Unit::SpellTakenCritChance ( Unit const *  caster,
SpellInfo const *  spellProto,
SpellSchoolMask  schoolMask,
float  doneChance,
WeaponAttackType  attackType,
bool  skipEffectCheck 
) const
11981{
11982 // not critting spell
11983 if (spellProto->HasAttribute(SPELL_ATTR2_CANT_CRIT))
11984 return 0.0f;
11985
11986 // Xinef: check if spell is capable of critting, auras requires special aura to crit so they can be skipped
11987 if (!skipEffectCheck && !spellProto->IsCritCapable())
11988 return 0.0f;
11989
11990 float crit_chance = doneChance;
11991 switch (spellProto->DmgClass)
11992 {
11994 {
11995 if (!spellProto->IsPositive())
11996 {
11997 // Modify critical chance by victim SPELL_AURA_MOD_ATTACKER_SPELL_CRIT_CHANCE
11998 // xinef: apply max and min only
12000 {
12003 }
12004
12005 Unit::ApplyResilience(this, &crit_chance, nullptr, false, CR_CRIT_TAKEN_SPELL);
12006 }
12007 // scripted (increase crit chance ... against ... target by x%
12008 if (caster)
12009 {
12010 AuraEffectList const& mOverrideClassScript = caster->GetAuraEffectsByType(SPELL_AURA_OVERRIDE_CLASS_SCRIPTS);
12011 for (AuraEffectList::const_iterator i = mOverrideClassScript.begin(); i != mOverrideClassScript.end(); ++i)
12012 {
12013 if (!((*i)->IsAffectedOnSpell(spellProto)))
12014 continue;
12015 int32 modChance = 0;
12016 switch ((*i)->GetMiscValue())
12017 {
12018 // Shatter
12019 case 911:
12020 modChance += 16;
12021 [[fallthrough]];
12022 case 910:
12023 modChance += 17;
12024 [[fallthrough]];
12025 case 849:
12026 modChance += 17;
12027 if (!HasAuraState(AURA_STATE_FROZEN, spellProto, caster))
12028 break;
12029 crit_chance += modChance;
12030 break;
12031 case 7917: // Glyph of Shadowburn
12032 if (HasAuraState(AURA_STATE_HEALTHLESS_35_PERCENT, spellProto, caster))
12033 crit_chance += (*i)->GetAmount();
12034 break;
12035 case 7997: // Renewed Hope
12036 case 7998:
12037 if (HasAura(6788))
12038 crit_chance += (*i)->GetAmount();
12039 break;
12040 default:
12041 break;
12042 }
12043 }
12044 // Custom crit by class
12045 switch (spellProto->SpellFamilyName)
12046 {
12047 case SPELLFAMILY_MAGE:
12048 // Glyph of Fire Blast
12049 if (spellProto->SpellFamilyFlags[0] == 0x2 && spellProto->SpellIconID == 12)
12051 if (AuraEffect const* aurEff = caster->GetAuraEffect(56369, EFFECT_0))
12052 crit_chance += aurEff->GetAmount();
12053 break;
12054 case SPELLFAMILY_DRUID:
12055 // Improved Faerie Fire
12057 if (AuraEffect const* aurEff = caster->GetDummyAuraEffect(SPELLFAMILY_DRUID, 109, 0))
12058 crit_chance += aurEff->GetAmount();
12059
12060 // cumulative effect - don't break
12061
12062 // Starfire
12063 if (spellProto->SpellFamilyFlags[0] & 0x4 && spellProto->SpellIconID == 1485)
12064 {
12065 // Improved Insect Swarm
12066 if (AuraEffect const* aurEff = caster->GetDummyAuraEffect(SPELLFAMILY_DRUID, 1771, 0))
12068 crit_chance += aurEff->GetAmount();
12069 break;
12070 }
12071 break;
12072 case SPELLFAMILY_ROGUE:
12073 // Shiv-applied poisons can't crit
12074 if (caster->FindCurrentSpellBySpellId(5938))
12075 crit_chance = 0.0f;
12076 break;
12078 // Flash of light
12079 if (spellProto->SpellFamilyFlags[0] & 0x40000000)
12080 {
12081 // Sacred Shield
12082 if (AuraEffect const* aura = GetAuraEffect(58597, 1, GetGUID()))
12083 crit_chance += aura->GetAmount();
12084 break;
12085 }
12086 // Exorcism
12087 else if (spellProto->GetCategory() == 19)
12088 {
12090 return 100.0f;
12091 break;
12092 }
12093 break;
12094 case SPELLFAMILY_SHAMAN:
12095 // Lava Burst
12096 if (spellProto->SpellFamilyFlags[1] & 0x00001000)
12097 {
12098 if (GetAuraEffect(SPELL_AURA_PERIODIC_DAMAGE, SPELLFAMILY_SHAMAN, 0x10000000, 0, 0, caster->GetGUID()))
12100 return 100.0f;
12101 break;
12102 }
12103 break;
12104 }
12105 }
12106 break;
12107 }
12109 // Custom crit by class
12110 if (caster)
12111 {
12112 switch (spellProto->SpellFamilyName)
12113 {
12114 case SPELLFAMILY_DRUID:
12115 // Rend and Tear - bonus crit chance for Ferocious Bite on bleeding targets
12116 if (spellProto->SpellFamilyFlags[0] & 0x00800000 && spellProto->SpellIconID == 1680 && HasAuraState(AURA_STATE_BLEEDING))
12117 {
12118 if (AuraEffect const* rendAndTear = caster->GetDummyAuraEffect(SPELLFAMILY_DRUID, 2859, 1))
12119 crit_chance += rendAndTear->GetAmount();
12120 break;
12121 }
12122 break;
12124 // Victory Rush
12125 if (spellProto->SpellFamilyFlags[1] & 0x100)
12126 {
12127 // Glyph of Victory Rush
12128 if (AuraEffect const* aurEff = caster->GetAuraEffect(58382, 0))
12129 crit_chance += aurEff->GetAmount();
12130 break;
12131 }
12132 break;
12133 }
12134 }
12135
12136 // 100% critical chance against sitting target
12138 {
12139 return 100.0f;
12140 }
12141 [[fallthrough]]; // TODO: Not sure whether the fallthrough was a mistake (forgetting a break) or intended. This should be double-checked.
12143 {
12144 // flat aura mods
12145 if (attackType == RANGED_ATTACK)
12147 else
12149
12150 // reduce crit chance from Rating for players
12151 if (attackType != RANGED_ATTACK)
12152 {
12153 // xinef: little hack, crit chance dont require caster to calculate, pass victim
12154 Unit::ApplyResilience(this, &crit_chance, nullptr, false, CR_CRIT_TAKEN_MELEE);
12155 }
12156 else
12157 Unit::ApplyResilience(this, &crit_chance, nullptr, false, CR_CRIT_TAKEN_RANGED);
12158
12159 // Apply crit chance from defence skill
12160 if (caster)
12161 crit_chance += (int32(caster->GetMaxSkillValueForLevel(this)) - int32(GetDefenseSkillValue(caster))) * 0.04f;
12162
12163 break;
12164 }
12165 // values overridden in spellmgr for lifebloom and earth shield
12167 default:
12168 return 0.0f;
12169 }
12170
12171 if (caster)
12172 {
12174 for (AuraEffectList::const_iterator i = mTotalAuraList.begin(); i != mTotalAuraList.end(); ++i)
12175 {
12176 if (caster->GetGUID() != (*i)->GetCasterGUID())
12177 continue;
12178
12179 crit_chance += (*i)->GetAmount();
12180 }
12181 }
12182
12183 // Modify critical chance by victim SPELL_AURA_MOD_ATTACKER_SPELL_AND_WEAPON_CRIT_CHANCE
12184 // xinef: should be calculated at the end
12185 if (!spellProto->IsPositive())
12187
12188 // xinef: can be negative!
12189 return crit_chance;
12190}
uint32 const CREATURE_TYPEMASK_DEMON_OR_UNDEAD
Definition: SharedDefines.h:2615
@ MECHANIC_KNOCKOUT
Definition: SharedDefines.h:1311
@ AURA_STATE_BLEEDING
Definition: SharedDefines.h:1282
@ SPELL_AURA_MOD_ATTACKER_SPELL_CRIT_CHANCE
Definition: SpellAuraDefines.h:242
int32 GetMaxPositiveAuraModifierByMiscMask(AuraType auratype, uint32 misc_mask, const AuraEffect *except=nullptr) const
Definition: Unit.cpp:5886
int32 GetMaxNegativeAuraModifierByMiscMask(AuraType auratype, uint32 misc_mask) const
Definition: Unit.cpp:5900

◆ StartReactiveTimer()

void Unit::StartReactiveTimer ( ReactiveType  reactive)
inline
#define REACTIVE_TIMER_START
Definition: Unit.h:1198

◆ StopAttackFaction()

void Unit::StopAttackFaction ( uint32  faction_id)
20174{
20175 if (Unit* victim = GetVictim())
20176 {
20177 if (victim->GetFactionTemplateEntry()->faction == faction_id)
20178 {
20179 AttackStop();
20180 if (IsNonMeleeSpellCast(false))
20182
20183 // melee and ranged forced attack cancel
20184 if (GetTypeId() == TYPEID_PLAYER)
20186 }
20187 }
20188
20189 AttackerSet const& attackers = getAttackers();
20190 for (AttackerSet::const_iterator itr = attackers.begin(); itr != attackers.end();)
20191 {
20192 if ((*itr)->GetFactionTemplateEntry()->faction == faction_id)
20193 {
20194 (*itr)->AttackStop();
20195 itr = attackers.begin();
20196 }
20197 else
20198 ++itr;
20199 }
20200
20202
20203 for (ControlSet::const_iterator itr = m_Controlled.begin(); itr != m_Controlled.end(); ++itr)
20204 (*itr)->StopAttackFaction(faction_id);
20205}
void deleteReferencesForFaction(uint32 faction)
Definition: HostileRefMgr.cpp:162

◆ StopAttackingInvalidTarget()

void Unit::StopAttackingInvalidTarget ( )
20208{
20209 AttackerSet const& attackers = getAttackers();
20210 for (AttackerSet::const_iterator itr = attackers.begin(); itr != attackers.end();)
20211 {
20212 Unit* attacker = (*itr);
20213 if (!attacker->IsValidAttackTarget(this))
20214 {
20215 attacker->AttackStop();
20216 if (attacker->GetTypeId() == TYPEID_PLAYER)
20217 {
20219 }
20220
20221 for (Unit* controled : attacker->m_Controlled)
20222 {
20223 if (controled->GetVictim() == this && !controled->IsValidAttackTarget(this))
20224 {
20225 controled->AttackStop();
20226 }
20227 }
20228
20229 itr = attackers.begin();
20230 }
20231 else
20232 {
20233 ++itr;
20234 }
20235 }
20236}

◆ StopMoving()

void Unit::StopMoving ( )
16737{
16739
16740 // not need send any packets if not in world or not moving
16741 if (!IsInWorld())
16742 return;
16743
16744 if (movespline->Finalized())
16745 return;
16746
16747 // Update position now since Stop does not start a new movement that can be updated later
16748 if (movespline->HasStarted())
16750
16751 Movement::MoveSplineInit init(this);
16752 init.Stop();
16753}
bool HasStarted() const
Definition: MoveSpline.h:129
void UpdateSplinePosition()
Definition: Unit.cpp:625

◆ StopMovingOnCurrentPos()

void Unit::StopMovingOnCurrentPos ( )
16776{
16778
16779 // not need send any packets if not in world
16780 if (!IsInWorld())
16781 return;
16782
16783 DisableSpline(); // pussywizard: required so Launch() won't recalculate position from previous spline
16784 Movement::MoveSplineInit init(this);
16785 init.MoveTo(GetPositionX(), GetPositionY(), GetPositionZ());
16786 init.SetFacing(GetOrientation());
16787 init.Launch();
16788}

◆ Talk() [1/2]

void Unit::Talk ( std::string_view  text,
ChatMsg  msgType,
Language  language,
float  textRange,
WorldObject const *  target 
)
virtual
21136{
21137 Acore::CustomChatTextBuilder builder(this, msgType, text, language, target);
21140 Cell::VisitWorldObjects(this, worker, textRange);
21141}
Definition: ChatTextBuilder.h:49
Definition: GridNotifiers.h:1706
Definition: GridNotifiers.h:589
static void VisitWorldObjects(WorldObject const *obj, T &visitor, float radius, bool dont_load=true)
Definition: CellImpl.h:193

◆ Talk() [2/2]

void Unit::Talk ( uint32  textId,
ChatMsg  msgType,
float  textRange,
WorldObject const *  target 
)
virtual
21172{
21173 if (!sObjectMgr->GetBroadcastText(textId))
21174 {
21175 LOG_ERROR("entities.unit", "Unit::Talk: `broadcast_text` (ID: {}) was not found", textId);
21176 return;
21177 }
21178
21179 Acore::BroadcastTextBuilder builder(this, msgType, textId, getGender(), target);
21182 Cell::VisitWorldObjects(this, worker, textRange);
21183}
Definition: ChatTextBuilder.h:31

◆ TauntApply()

void Unit::TauntApply ( Unit victim)
14535{
14537
14538 if (!taunter || (taunter->GetTypeId() == TYPEID_PLAYER && taunter->ToPlayer()->IsGameMaster()))
14539 return;
14540
14541 if (!CanHaveThreatList())
14542 return;
14543
14544 Creature* creature = ToCreature();
14545
14546 if (creature->HasReactState(REACT_PASSIVE))
14547 return;
14548
14549 Unit* target = GetVictim();
14550 if (target && target == taunter)
14551 return;
14552
14553 SetInFront(taunter);
14554 if (creature->IsAIEnabled)
14555 creature->AI()->AttackStart(taunter);
14556
14557 //m_ThreatMgr.tauntApply(taunter);
14558}
void SetInFront(WorldObject const *target)
Definition: Unit.cpp:20613

◆ TauntFadeOut()

void Unit::TauntFadeOut ( Unit taunter)
14563{
14565
14566 if (!taunter || (taunter->GetTypeId() == TYPEID_PLAYER && taunter->ToPlayer()->IsGameMaster()))
14567 return;
14568
14569 if (!CanHaveThreatList())
14570 return;
14571
14572 Creature* creature = ToCreature();
14573
14574 if (creature->HasReactState(REACT_PASSIVE))
14575 return;
14576
14577 Unit* target = GetVictim();
14578 if (!target || target != taunter)
14579 return;
14580
14582 {
14583 if (creature->IsAIEnabled)
14585 return;
14586 }
14587
14588 target = creature->SelectVictim(); // might have more taunt auras remaining
14589
14590 if (target && target != taunter)
14591 {
14592 SetInFront(target);
14593 if (creature->IsAIEnabled)
14594 creature->AI()->AttackStart(target);
14595 }
14596}
@ EVADE_REASON_NO_HOSTILES
Definition: CreatureAI.h:88
virtual void EnterEvadeMode(EvadeReason why=EVADE_REASON_OTHER)
Definition: CreatureAI.cpp:195
Unit * SelectVictim()
Definition: Unit.cpp:14600
bool isThreatListEmpty() const
Definition: ThreatMgr.h:225

◆ TextEmote() [1/2]

void Unit::TextEmote ( std::string_view  text,
WorldObject const *  target = nullptr,
bool  isBossEmote = false 
)
virtual

Reimplemented in Player.

21154{
21156}
@ CONFIG_LISTEN_RANGE_TEXTEMOTE
Definition: IWorld.h:189
@ CHAT_MSG_RAID_BOSS_EMOTE
Definition: SharedDefines.h:3165
@ CHAT_MSG_MONSTER_EMOTE
Definition: SharedDefines.h:3140

◆ TextEmote() [2/2]

void Unit::TextEmote ( uint32  textId,
WorldObject const *  target = nullptr,
bool  isBossEmote = false 
)
virtual

Reimplemented in Player.

21196{
21197 Talk(textId, isBossEmote ? CHAT_MSG_RAID_BOSS_EMOTE : CHAT_MSG_MONSTER_EMOTE, sWorld->getFloatConfig(CONFIG_LISTEN_RANGE_TEXTEMOTE), target);
21198}

◆ ToPet()

Pet * Unit::ToPet ( )
inline
2393{ if (IsPet()) return reinterpret_cast<Pet*>(this); else return nullptr; }

◆ ToTempSummon() [1/2]

TempSummon * Unit::ToTempSummon ( )
inline
2395{ if (IsSummon()) return reinterpret_cast<TempSummon*>(this); else return nullptr; }

◆ ToTempSummon() [2/2]

const TempSummon * Unit::ToTempSummon ( ) const
inline
2396{ if (IsSummon()) return reinterpret_cast<const TempSummon*>(this); else return nullptr; }

◆ ToTotem()

Totem * Unit::ToTotem ( )
inline
2394{ if (IsTotem()) return reinterpret_cast<Totem*>(this); else return nullptr; }
Definition: Totem.h:38

◆ TriggerAurasProcOnEvent() [1/3]

void Unit::TriggerAurasProcOnEvent ( CalcDamageInfo damageInfo)
16648{
16649 DamageInfo dmgInfo = DamageInfo(damageInfo);
16650 TriggerAurasProcOnEvent(nullptr, nullptr, damageInfo.target, damageInfo.procAttacker, damageInfo.procVictim, 0, 0, damageInfo.procEx, nullptr, &dmgInfo, nullptr);
16651}
void TriggerAurasProcOnEvent(CalcDamageInfo &damageInfo)
Definition: Unit.cpp:16647

◆ TriggerAurasProcOnEvent() [2/3]

void Unit::TriggerAurasProcOnEvent ( ProcEventInfo eventInfo,
std::list< AuraApplication * > &  procAuras 
)
16673{
16674 for (std::list<AuraApplication*>::iterator itr = aurasTriggeringProc.begin(); itr != aurasTriggeringProc.end(); ++itr)
16675 {
16676 if (!(*itr)->GetRemoveMode())
16677 (*itr)->GetBase()->TriggerProcOnEvent(*itr, eventInfo);
16678 }
16679}

◆ TriggerAurasProcOnEvent() [3/3]

void Unit::TriggerAurasProcOnEvent ( std::list< AuraApplication * > *  myProcAuras,
std::list< AuraApplication * > *  targetProcAuras,
Unit actionTarget,
uint32  typeMaskActor,
uint32  typeMaskActionTarget,
uint32  spellTypeMask,
uint32  spellPhaseMask,
uint32  hitMask,
Spell spell,
DamageInfo damageInfo,
HealInfo healInfo 
)
16654{
16655 // prepare data for self trigger
16656 ProcEventInfo myProcEventInfo = ProcEventInfo(this, actionTarget, actionTarget, typeMaskActor, spellTypeMask, spellPhaseMask, hitMask, spell, damageInfo, healInfo);
16657 std::list<AuraApplication*> myAurasTriggeringProc;
16658 GetProcAurasTriggeredOnEvent(myAurasTriggeringProc, myProcAuras, myProcEventInfo);
16659
16660 // prepare data for target trigger
16661 ProcEventInfo targetProcEventInfo = ProcEventInfo(this, actionTarget, this, typeMaskActionTarget, spellTypeMask, spellPhaseMask, hitMask, spell, damageInfo, healInfo);
16662 std::list<AuraApplication*> targetAurasTriggeringProc;
16663 if (typeMaskActionTarget)
16664 GetProcAurasTriggeredOnEvent(targetAurasTriggeringProc, targetProcAuras, targetProcEventInfo);
16665
16666 TriggerAurasProcOnEvent(myProcEventInfo, myAurasTriggeringProc);
16667
16668 if (typeMaskActionTarget)
16669 TriggerAurasProcOnEvent(targetProcEventInfo, targetAurasTriggeringProc);
16670}
void GetProcAurasTriggeredOnEvent(std::list< AuraApplication * > &aurasTriggeringProc, std::list< AuraApplication * > *procAuras, ProcEventInfo eventInfo)
Definition: Unit.cpp:16617

◆ UnsummonAllTotems()

void Unit::UnsummonAllTotems ( bool  onDeath = false)
11154{
11155 for (uint8 i = 0; i < MAX_SUMMON_SLOT; ++i)
11156 {
11157 if (!m_SummonSlot[i])
11158 {
11159 continue;
11160 }
11161
11162 if (Creature* OldTotem = GetMap()->GetCreature(m_SummonSlot[i]))
11163 {
11164 if (OldTotem->IsSummon())
11165 {
11166 if (!(onDeath && !IsPlayer() && OldTotem->IsGuardian()))
11167 {
11168 OldTotem->ToTempSummon()->UnSummon();
11169 }
11170 }
11171 }
11172 }
11173}

◆ Update()

void Unit::Update ( uint32  time)
overridevirtual

Reimplemented from WorldObject.

403{
404 sScriptMgr->OnUnitUpdate(this, p_time);
405
406 // WARNING! Order of execution here is important, do not change.
407 // Spells must be processed with event system BEFORE they go to _UpdateSpells.
408 // Or else we may have some SPELL_STATE_FINISHED spells stalled in pointers, that is bad.
409 m_Events.Update(p_time);
410
411 if (!IsInWorld())
412 return;
413
414 // pussywizard:
415 if (GetTypeId() != TYPEID_PLAYER || (!ToPlayer()->IsBeingTeleported() && !bRequestForcedVisibilityUpdate))
416 {
418 {
420 {
422 //ExecuteDelayedUnitRelocationEvent();
424 }
425 else
427 }
429 {
430 if (m_delayed_unit_ai_notify_timer <= p_time)
431 {
434 }
435 else
437 }
438 }
439
440 _UpdateSpells( p_time );
441
442 if (CanHaveThreatList() && GetThreatMgr().isNeedUpdateToClient(p_time))
444
445 // update combat timer only for players and pets (only pets with PetAI)
447 {
448 // Check UNIT_STATE_MELEE_ATTACKING or UNIT_STATE_CHASE (without UNIT_STATE_FOLLOW in this case) so pets can reach far away
449 // targets without stopping half way there and running off.
450 // These flags are reset after target dies or another command is given.
452 {
453 // m_CombatTimer set at aura start and it will be freeze until aura removing
454 if (m_CombatTimer <= p_time)
456 else
457 m_CombatTimer -= p_time;
458 }
459 }
460
463 {
464 while (!extraAttacksTargets.empty())
465 {
466 auto itr = extraAttacksTargets.begin();
467 ObjectGuid targetGuid = itr->first;
468 uint32 count = itr->second;
469 extraAttacksTargets.erase(itr);
470 if (Unit* victim = ObjectAccessor::GetUnit(*this, targetGuid))
471 {
473 || victim->IsWithinMeleeRange(this))
474 {
475 HandleProcExtraAttackFor(victim, count);
476 }
477 }
478 }
480 }
481
482 // not implemented before 3.0.2
483 // xinef: if attack time > 0, reduce by diff
484 // if on next update, attack time < 0 assume player didnt attack - set to 0
485 bool suspendAttackTimer = false;
486 bool suspendRangedAttackTimer = false;
488 {
489 for (Spell* spell : m_currentSpells)
490 {
491 if (spell)
492 {
493 if (spell->GetSpellInfo()->HasAttribute(SPELL_ATTR2_DO_NOT_RESET_COMBAT_TIMERS))
494 {
495 if (spell->IsChannelActive())
496 {
497 suspendRangedAttackTimer = true;
498 }
499
500 suspendAttackTimer = true;
501 break;
502 }
503 }
504 }
505 }
506
507 if (!suspendAttackTimer)
508 {
509 if (int32 base_attack = getAttackTimer(BASE_ATTACK))
510 {
511 setAttackTimer(BASE_ATTACK, base_attack > 0 ? base_attack - (int32) p_time : 0);
512 }
513
514 if (int32 off_attack = getAttackTimer(OFF_ATTACK))
515 {
516 setAttackTimer(OFF_ATTACK, off_attack > 0 ? off_attack - (int32) p_time : 0);
517 }
518 }
519
520 if (!suspendRangedAttackTimer)
521 {
522 if (int32 ranged_attack = getAttackTimer(RANGED_ATTACK))
523 {
524 setAttackTimer(RANGED_ATTACK, ranged_attack > 0 ? ranged_attack - (int32)p_time : 0);
525 }
526 }
527
528 // update abilities available only for fraction of time
529 UpdateReactives(p_time);
530
534
535 UpdateSplineMovement(p_time);
536 GetMotionMaster()->UpdateMotion(p_time);
537}
@ AURA_STATE_HEALTH_ABOVE_75_PERCENT
Definition: SharedDefines.h:1287
void Update(uint32 p_time)
Definition: EventProcessor.cpp:40
bool IsEmpty() const
Definition: LinkedList.h:97
std::unordered_set< Unit * > i_objectsForDelayedVisibility
Definition: Map.h:388
void UpdateMotion(uint32 diff)
Definition: MotionMaster.cpp:103
void _UpdateSpells(uint32 time)
Definition: Unit.cpp:3785
void UpdateSplineMovement(uint32 t_diff)
Definition: Unit.cpp:593
void UpdateReactives(uint32 p_time)
Definition: Unit.cpp:17001
void ExecuteDelayedUnitAINotifyEvent()
Definition: Unit.cpp:20602
void HandleProcExtraAttackFor(Unit *victim, uint32 count)
Definition: Unit.cpp:2706
void SendThreatListUpdate()
Definition: Unit.cpp:20084

◆ UpdateAllResistances()

void Unit::UpdateAllResistances ( )
virtual
55{
58}

◆ UpdateAllStats()

virtual bool Unit::UpdateAllStats ( )
pure virtual

Implemented in Creature, Guardian, Player, and Totem.

◆ UpdateArmor()

virtual void Unit::UpdateArmor ( )
pure virtual

Implemented in Creature, Guardian, Player, and Totem.

◆ UpdateAttackPowerAndDamage()

virtual void Unit::UpdateAttackPowerAndDamage ( bool  ranged = false)
pure virtual

Implemented in Creature, Guardian, Player, and Totem.

◆ UpdateAuraForGroup()

void Unit::UpdateAuraForGroup ( uint8  slot)
17231{
17232 if (slot >= MAX_AURAS) // slot not found, return
17233 return;
17234 if (Player* player = ToPlayer())
17235 {
17236 if (player->GetGroup())
17237 {
17238 player->SetGroupUpdateFlag(GROUP_UPDATE_FLAG_AURAS);
17239 player->SetAuraUpdateMaskForRaid(slot);
17240 }
17241 }
17242 else if (GetTypeId() == TYPEID_UNIT && IsPet())
17243 {
17244 Pet* pet = ((Pet*)this);
17245 if (pet->isControlled())
17246 {
17247 Unit* owner = GetOwner();
17248 if (owner && (owner->GetTypeId() == TYPEID_PLAYER) && owner->ToPlayer()->GetGroup())
17249 {
17251 pet->SetAuraUpdateMaskForRaid(slot);
17252 }
17253 }
17254 }
17255}
@ GROUP_UPDATE_FLAG_PET_AURAS
Definition: Group.h:117
@ GROUP_UPDATE_FLAG_AURAS
Definition: Group.h:108
#define MAX_AURAS
Definition: SpellAuraDefines.h:21
void SetAuraUpdateMaskForRaid(uint8 slot)
Definition: Pet.h:135

◆ UpdateCharmAI()

void Unit::UpdateCharmAI ( )
15623{
15624 if (GetTypeId() == TYPEID_PLAYER)
15625 return;
15626
15627 if (i_disabledAI) // disabled AI must be primary AI
15628 {
15629 if (!IsCharmed())
15630 {
15631 delete i_AI;
15633 i_disabledAI = nullptr;
15634 }
15635 }
15636 else
15637 {
15638 if (IsCharmed())
15639 {
15641 if (isPossessed() || IsVehicle())
15642 i_AI = new PossessedAI(ToCreature());
15643 else
15644 i_AI = new PetAI(ToCreature());
15645 }
15646 }
15647}
Definition: PetAI.h:47
Definition: PassiveAI.h:37

◆ UpdateDamagePhysical()

void Unit::UpdateDamagePhysical ( WeaponAttackType  attType)
virtual

Reimplemented in Guardian, and Totem.

61{
62 float totalMin = 0.f;
63 float totalMax = 0.f;
64
65 float tmpMin, tmpMax;
66 for (uint8 i = 0; i < MAX_ITEM_PROTO_DAMAGES; ++i)
67 {
68 CalculateMinMaxDamage(attType, false, true, tmpMin, tmpMax, i);
69 totalMin += tmpMin;
70 totalMax += tmpMax;
71 }
72
73 switch (attType)
74 {
75 case BASE_ATTACK:
76 default:
79 break;
80 case OFF_ATTACK:
83 break;
84 case RANGED_ATTACK:
87 break;
88 }
89}
void SetStatFloatValue(uint16 index, float value)
Definition: Object.cpp:790

◆ UpdateHeight()

void Unit::UpdateHeight ( float  newZ)

Only server-side height update, does not broadcast to client.

20078{
20080 if (IsVehicle())
20082}
void RelocatePassengers()
Definition: Vehicle.cpp:501

◆ UpdateInterruptMask()

void Unit::UpdateInterruptMask ( )
759{
760 m_interruptMask = 0;
761 for (AuraApplicationList::const_iterator i = m_interruptableAuras.begin(); i != m_interruptableAuras.end(); ++i)
762 m_interruptMask |= (*i)->GetBase()->GetSpellInfo()->AuraInterruptFlags;
763
765 if (spell->getState() == SPELL_STATE_CASTING)
766 m_interruptMask |= spell->m_spellInfo->ChannelInterruptFlags;
767}

◆ UpdateMaxHealth()

virtual void Unit::UpdateMaxHealth ( )
pure virtual

Implemented in Creature, Guardian, Player, and Totem.

◆ UpdateMaxPower()

virtual void Unit::UpdateMaxPower ( Powers  power)
pure virtual

Implemented in Creature, Guardian, Player, and Totem.

◆ UpdateObjectVisibility()

void Unit::UpdateObjectVisibility ( bool  forced = true,
bool  fromUpdate = false 
)
overridevirtual

Reimplemented from WorldObject.

19163{
19164 if (!forced)
19166 else
19167 {
19169 Acore::AIRelocationNotifier notifier(*this);
19170 float radius = 60.0f;
19171 Cell::VisitAllObjects(this, notifier, radius);
19172 }
19173}
virtual void UpdateObjectVisibility(bool forced=true, bool fromUpdate=false)
Definition: Object.cpp:2883

◆ UpdateOrientation()

void Unit::UpdateOrientation ( float  orientation)

Only server-side orientation update, does not broadcast to client.

20070{
20071 SetOrientation(orientation);
20072 if (IsVehicle())
20074}

◆ UpdatePosition() [1/2]

bool Unit::UpdatePosition ( const Position pos,
bool  teleport = false 
)
inline
1765{ return UpdatePosition(pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), pos.GetOrientation(), teleport); }

◆ UpdatePosition() [2/2]

bool Unit::UpdatePosition ( float  x,
float  y,
float  z,
float  ang,
bool  teleport = false 
)
virtual

Reimplemented in Player.

20032{
20033 if (!Acore::IsValidMapCoord(x, y, z, orientation))
20034 return false;
20035
20036 float old_orientation = GetOrientation();
20037 float current_z = GetPositionZ();
20038 bool turn = (old_orientation != orientation);
20039 bool relocated = (teleport || GetPositionX() != x || GetPositionY() != y || current_z != z);
20040
20041 if (!GetVehicle())
20042 {
20043 uint32 mask = 0;
20044 if (turn) mask |= AURA_INTERRUPT_FLAG_TURNING;
20045 if (relocated) mask |= AURA_INTERRUPT_FLAG_MOVE;
20046 if (mask)
20048 }
20049
20050 if (relocated)
20051 {
20052 if (GetTypeId() == TYPEID_PLAYER)
20053 GetMap()->PlayerRelocation(ToPlayer(), x, y, z, orientation);
20054 else
20055 GetMap()->CreatureRelocation(ToCreature(), x, y, z, orientation);
20056 }
20057 else if (turn)
20058 {
20059 UpdateOrientation(orientation);
20060
20061 if (GetTypeId() == TYPEID_PLAYER && ToPlayer()->GetFarSightDistance())
20063 }
20064
20065 return (relocated || turn);
20066}
void PlayerRelocation(Player *, float x, float y, float z, float o)
Definition: Map.cpp:1003
void CreatureRelocation(Creature *creature, float x, float y, float z, float o)
Definition: Map.cpp:1025
void UpdateOrientation(float orientation)
Only server-side orientation update, does not broadcast to client.
Definition: Unit.cpp:20069
bool IsValidMapCoord(float c)
Definition: GridDefines.h:216

◆ UpdateReactives()

void Unit::UpdateReactives ( uint32  p_time)
17002{
17003 for (uint8 i = 0; i < MAX_REACTIVE; ++i)
17004 {
17005 ReactiveType reactive = ReactiveType(i);
17006
17007 if (!m_reactiveTimer[reactive])
17008 continue;
17009
17010 if (m_reactiveTimer[reactive] <= p_time)
17011 {
17012 m_reactiveTimer[reactive] = 0;
17013
17014 switch (reactive)
17015 {
17016 case REACTIVE_DEFENSE:
17019 break;
17023 break;
17024 case REACTIVE_OVERPOWER:
17025 if (getClass() == CLASS_WARRIOR)
17026 {
17028 }
17029 break;
17031 if (IsHunterPet())
17033 break;
17034 default:
17035 break;
17036 }
17037 }
17038 else
17039 {
17040 m_reactiveTimer[reactive] -= p_time;
17041 }
17042 }
17043}
ReactiveType
Definition: Unit.h:1201

◆ UpdateResistances()

virtual void Unit::UpdateResistances ( uint32  school)
pure virtual

Implemented in Creature, Player, and Totem.

◆ UpdateSpeed()

void Unit::UpdateSpeed ( UnitMoveType  mtype,
bool  forced 
)
Todo:
possible affect only on MOVE_RUN
14136{
14137 int32 main_speed_mod = 0;
14138 float stack_bonus = 1.0f;
14139 float non_stack_bonus = 1.0f;
14140
14141 switch (mtype)
14142 {
14143 // Only apply debuffs
14144 case MOVE_FLIGHT_BACK:
14145 case MOVE_RUN_BACK:
14146 case MOVE_SWIM_BACK:
14147 case MOVE_WALK:
14148 break;
14149 case MOVE_RUN:
14150 {
14151 if (IsMounted()) // Use on mount auras
14152 {
14156 }
14157 else
14158 {
14162 }
14163 break;
14164 }
14165 case MOVE_SWIM:
14166 {
14167 // xinef: check for forced_speed_mod of sea turtle
14169 for (Unit::AuraEffectList::const_iterator itr = swimAuras.begin(); itr != swimAuras.end(); ++itr)
14170 {
14171 // xinef: sea turtle only, it is not affected by any increasing / decreasing effects
14172 if ((*itr)->GetId() == 64731 /*SPELL_SEA_TURTLE*/)
14173 {
14174 SetSpeed(mtype, AddPct(non_stack_bonus, (*itr)->GetAmount()), forced);
14175 return;
14176 }
14177 else if (
14178 // case: increase speed
14179 ((*itr)->GetAmount() > 0 && (*itr)->GetAmount() > main_speed_mod) ||
14180 // case: decrease speed
14181 ((*itr)->GetAmount() < 0 && (*itr)->GetAmount() < main_speed_mod)
14182 )
14183 {
14184 main_speed_mod = (*itr)->GetAmount();
14185 }
14186 }
14187 break;
14188 }
14189 case MOVE_FLIGHT:
14190 {
14191 if (GetTypeId() == TYPEID_UNIT && IsControlledByPlayer()) // not sure if good for pet
14192 {
14195
14196 // for some spells this mod is applied on vehicle owner
14197 int32 owner_speed_mod = 0;
14198
14199 if (Unit* owner = GetCharmer())
14200 owner_speed_mod = owner->GetMaxPositiveAuraModifier(SPELL_AURA_MOD_INCREASE_VEHICLE_FLIGHT_SPEED);
14201
14202 main_speed_mod = std::max(main_speed_mod, owner_speed_mod);
14203 }
14204 else if (IsMounted())
14205 {
14208 }
14209 else // Use not mount (shapeshift for example) auras (should stack)
14211
14213
14214 // Update speed for vehicle if available
14215 if (GetTypeId() == TYPEID_PLAYER && GetVehicle())
14217 break;
14218 }
14219 default:
14220 LOG_ERROR("entities.unit", "Unit::UpdateSpeed: Unsupported move type ({})", mtype);
14221 return;
14222 }
14223
14224 // now we ready for speed calculation
14225 float speed = std::max(non_stack_bonus, stack_bonus);
14226 if (main_speed_mod)
14227 AddPct(speed, main_speed_mod);
14228
14229 switch (mtype)
14230 {
14231 case MOVE_RUN:
14232 case MOVE_SWIM:
14233 case MOVE_FLIGHT:
14234 {
14235 // Set creature speed rate
14236 if (GetTypeId() == TYPEID_UNIT)
14237 speed *= ToCreature()->GetCreatureTemplate()->speed_run; // at this point, MOVE_WALK is never reached
14238
14239 // Normalize speed by 191 aura SPELL_AURA_USE_NORMAL_MOVEMENT_SPEED if need
14242 {
14243 if (Creature* creature = ToCreature())
14244 {
14245 uint32 immuneMask = creature->GetCreatureTemplate()->MechanicImmuneMask;
14246 if (immuneMask & (1 << (MECHANIC_SNARE - 1)) || immuneMask & (1 << (MECHANIC_DAZE - 1)))
14247 break;
14248 }
14249
14250 // Use speed from aura
14251 float max_speed = normalization / (IsControlledByPlayer() ? playerBaseMoveSpeed[mtype] : baseMoveSpeed[mtype]);
14252 if (speed > max_speed)
14253 speed = max_speed;
14254 }
14255 break;
14256 }
14257 default:
14258 break;
14259 }
14260
14261 int32 slowFromHealth = 0;
14262 Creature* creature = ToCreature();
14263 // ignore pets, player owned vehicles, and mobs immune to snare
14264 if (creature
14265 && !IsPet()
14266 && !(IsControlledByPlayer() && IsVehicle())
14268 && !(creature->IsDungeonBoss()))
14269 {
14270 // 1.6% for each % under 30.
14271 // use min(0, health-30) so that we don't boost mobs above 30.
14272 slowFromHealth = (int32) std::min(0.0f, (1.66f * (GetHealthPct() - 30.0f)));
14273 }
14274
14275 if (slowFromHealth)
14276 {
14277 AddPct(speed, slowFromHealth);
14278 }
14279
14280 // Apply strongest slow aura mod to speed
14282 if (slow)
14283 AddPct(speed, slow);
14284
14285 if (float minSpeedMod = (float)GetMaxPositiveAuraModifier(SPELL_AURA_MOD_MINIMUM_SPEED))
14286 {
14287 float base_speed = (GetTypeId() == TYPEID_UNIT ? ToCreature()->GetCreatureTemplate()->speed_run : 1.0f);
14288 float min_speed = base_speed * (minSpeedMod / 100.0f);
14289 if (speed < min_speed)
14290 speed = min_speed;
14291 }
14292
14293 SetSpeed(mtype, speed, forced);
14294}
@ MECHANIC_DAZE
Definition: SharedDefines.h:1324
@ SPELL_AURA_MOD_FLIGHT_SPEED_NOT_STACK
Definition: SpellAuraDefines.h:274
@ SPELL_AURA_MOD_INCREASE_FLIGHT_SPEED
Definition: SpellAuraDefines.h:271
@ SPELL_AURA_MOD_MOUNTED_FLIGHT_SPEED_ALWAYS
Definition: SpellAuraDefines.h:272
@ SPELL_AURA_MOD_INCREASE_SPEED
Definition: SpellAuraDefines.h:94
@ SPELL_AURA_MOD_MOUNTED_SPEED_NOT_STACK
Definition: SpellAuraDefines.h:235
@ SPELL_AURA_MOD_SPEED_NOT_STACK
Definition: SpellAuraDefines.h:234
@ SPELL_AURA_MOD_INCREASE_VEHICLE_FLIGHT_SPEED
Definition: SpellAuraDefines.h:269
@ SPELL_AURA_MOD_INCREASE_SWIM_SPEED
Definition: SpellAuraDefines.h:121
@ SPELL_AURA_MOD_VEHICLE_SPEED_ALWAYS
Definition: SpellAuraDefines.h:273
@ SPELL_AURA_MOD_MINIMUM_SPEED
Definition: SpellAuraDefines.h:368
@ SPELL_AURA_MOD_SPEED_ALWAYS
Definition: SpellAuraDefines.h:192
@ SPELL_AURA_MOD_MOUNTED_SPEED_ALWAYS
Definition: SpellAuraDefines.h:193
@ SPELL_AURA_MOD_INCREASE_MOUNTED_SPEED
Definition: SpellAuraDefines.h:95
@ SPELL_AURA_USE_NORMAL_MOVEMENT_SPEED
Definition: SpellAuraDefines.h:254
float speed_run
Definition: CreatureData.h:194

◆ UpdateSplineMovement()

void Unit::UpdateSplineMovement ( uint32  t_diff)
private
594{
595 if (movespline->Finalized())
596 return;
597
598 // xinef: process movementinform
599 // this code cant be placed inside EscortMovementGenerator, because we cant delete active MoveGen while it is updated
600 SplineHandler handler(this);
601 movespline->updateState(t_diff, handler);
602 // Xinef: Spline was cleared by StopMoving, return
603 if (!movespline->Initialized())
604 {
606 return;
607 }
608
609 bool arrived = movespline->Finalized();
610
611 if (arrived)
612 {
614
617 }
618
619 // pussywizard: update always! not every 400ms, because movement generators need the actual position
620 //m_movesplineTimer.Update(t_diff);
621 //if (m_movesplineTimer.Passed() || arrived)
623}
@ UNIT_BYTES_1_OFFSET_ANIM_TIER
Definition: Unit.h:47
uint8 GetAnimationType() const
Definition: MoveSpline.h:125
void updateState(int32 difftime, UpdateHandler &handler)
Definition: MoveSpline.h:98
bool HasAnimation() const
Definition: MoveSpline.h:124
Definition: Unit.cpp:573

◆ UpdateSplinePosition()

void Unit::UpdateSplinePosition ( )
private
626{
627 //static uint32 const positionUpdateDelay = 400;
628
629 //m_movesplineTimer.Reset(positionUpdateDelay);
631
633 {
635 pos.m_positionX = loc.x;
636 pos.m_positionY = loc.y;
637 pos.m_positionZ = loc.z;
639
640 if (TransportBase* transport = GetDirectTransport())
641 transport->CalculatePassengerPosition(loc.x, loc.y, loc.z, &loc.orientation);
642 }
643
644 // Xinef: this is bullcrap, if we had spline running update orientation along with position
645 //if (HasUnitState(UNIT_STATE_CANNOT_TURN))
646 // loc.orientation = GetOrientation();
647
648 if (GetTypeId() == TYPEID_PLAYER)
649 UpdatePosition(loc.x, loc.y, loc.z, loc.orientation);
650 else
651 ToCreature()->SetPosition(loc.x, loc.y, loc.z, loc.orientation);
652}
void SetPosition(float x, float y, float z, float o)
Definition: Creature.cpp:3027
Location ComputePosition() const
Definition: MoveSpline.cpp:26
bool onTransport
Definition: MoveSpline.h:127
Definition: VehicleDefines.h:107
TransportBase * GetDirectTransport() const
Returns the transport this unit is on directly (if on vehicle and transport, return vehicle)
Definition: Unit.cpp:18799
Definition: MoveSpline.h:27
float orientation
Definition: MoveSpline.h:33
Position pos
Definition: Object.h:285
float m_positionZ
Definition: Position.h:58
float m_positionX
Definition: Position.h:56
float m_positionY
Definition: Position.h:57

◆ UpdateStats()

virtual bool Unit::UpdateStats ( Stats  stat)
pure virtual

Implemented in Creature, Guardian, Player, and Totem.

◆ Whisper() [1/2]

void Unit::Whisper ( std::string_view  text,
Language  language,
Player target,
bool  isBossWhisper = false 
)
virtual

Reimplemented in Player.

21159{
21160 if (!target)
21161 {
21162 return;
21163 }
21164
21166 WorldPacket data;
21167 ChatHandler::BuildChatPacket(data, isBossWhisper ? CHAT_MSG_RAID_BOSS_WHISPER : CHAT_MSG_MONSTER_WHISPER, language, this, target, text, 0, "", locale);
21168 target->SendDirectMessage(&data);
21169}
LocaleConstant
Definition: Common.h:74
@ CHAT_MSG_MONSTER_WHISPER
Definition: SharedDefines.h:3139
@ CHAT_MSG_RAID_BOSS_WHISPER
Definition: SharedDefines.h:3166
static size_t BuildChatPacket(WorldPacket &data, ChatMsg chatType, Language language, ObjectGuid senderGUID, ObjectGuid receiverGUID, std::string_view message, uint8 chatTag, std::string const &senderName="", std::string const &receiverName="", uint32 achievementId=0, bool gmMessage=false, std::string const &channelName="")
Definition: Chat.cpp:192
LocaleConstant GetSessionDbLocaleIndex() const
Definition: WorldSession.h:496

◆ Whisper() [2/2]

void Unit::Whisper ( uint32  textId,
Player target,
bool  isBossWhisper = false 
)
virtual

Reimplemented in Player.

21201{
21202 if (!target)
21203 {
21204 return;
21205 }
21206
21207 BroadcastText const* bct = sObjectMgr->GetBroadcastText(textId);
21208 if (!bct)
21209 {
21210 LOG_ERROR("entities.unit", "Unit::Whisper: `broadcast_text` was not {} found", textId);
21211 return;
21212 }
21213
21215 WorldPacket data;
21216 ChatHandler::BuildChatPacket(data, isBossWhisper ? CHAT_MSG_RAID_BOSS_WHISPER : CHAT_MSG_MONSTER_WHISPER, LANG_UNIVERSAL, this, target, bct->GetText(locale, getGender()), 0, "", locale);
21217 target->SendDirectMessage(&data);
21218}
Definition: ObjectMgr.h:435
std::string const & GetText(LocaleConstant locale=DEFAULT_LOCALE, uint8 gender=GENDER_MALE, bool forceGender=false) const
Definition: ObjectMgr.h:457

◆ Yell() [1/2]

void Unit::Yell ( std::string_view  text,
Language  language,
WorldObject const *  target = nullptr 
)
virtual

Reimplemented in Player.

21149{
21150 Talk(text, CHAT_MSG_MONSTER_YELL, language, sWorld->getFloatConfig(CONFIG_LISTEN_RANGE_YELL), target);
21151}
@ CONFIG_LISTEN_RANGE_YELL
Definition: IWorld.h:190
@ CHAT_MSG_MONSTER_YELL
Definition: SharedDefines.h:3138

◆ Yell() [2/2]

void Unit::Yell ( uint32  textId,
WorldObject const *  target = nullptr 
)
virtual

Reimplemented in Player.

21191{
21192 Talk(textId, CHAT_MSG_MONSTER_YELL, sWorld->getFloatConfig(CONFIG_LISTEN_RANGE_YELL), target);
21193}

Member Data Documentation

◆ _charmThreatInfo

CharmThreatMap Unit::_charmThreatInfo
protected

◆ _instantCast

bool Unit::_instantCast
protected

◆ _isWalkingBeforeCharm

bool Unit::_isWalkingBeforeCharm
private

Are we walking before we were charmed?

◆ _lastDamagedTargetGuid

ObjectGuid Unit::_lastDamagedTargetGuid
private

◆ _lastExtraAttackSpell

uint32 Unit::_lastExtraAttackSpell
private

◆ _lastLiquid

LiquidTypeEntry const* Unit::_lastLiquid
protected

◆ _oldFactionId

uint32 Unit::_oldFactionId
private

faction before charm

◆ _redirectThreatInfo

RedirectThreatInfo Unit::_redirectThreatInfo
private

◆ bRequestForcedVisibilityUpdate

bool Unit::bRequestForcedVisibilityUpdate

◆ extraAttacksTargets

std::unordered_map<ObjectGuid , uint32 > Unit::extraAttacksTargets
private

◆ i_AI

UnitAI* Unit::i_AI
protected

◆ i_disabledAI

UnitAI * Unit::i_disabledAI
protected

◆ i_motionMaster

MotionMaster* Unit::i_motionMaster
protected

◆ IsAIEnabled

bool Unit::IsAIEnabled

◆ m_appliedAuras

AuraApplicationMap Unit::m_appliedAuras
protected

◆ m_applyResilience

bool Unit::m_applyResilience
protected

◆ m_attackers

AttackerSet Unit::m_attackers
protected

◆ m_attacking

Unit* Unit::m_attacking
protected

◆ m_attackTimer

int32 Unit::m_attackTimer[MAX_ATTACK]
protected

◆ m_auraModifiersGroup

float Unit::m_auraModifiersGroup[UNIT_MOD_END][MODIFIER_TYPE_END]
protected

◆ m_auraStateAuras

AuraStateAurasMap Unit::m_auraStateAuras
protected

◆ m_auraUpdateIterator

AuraMap::iterator Unit::m_auraUpdateIterator
protected

◆ m_AutoRepeatFirstCast

bool Unit::m_AutoRepeatFirstCast
protected

◆ m_baseSpellCritChance

int32 Unit::m_baseSpellCritChance

◆ m_canDualWield

bool Unit::m_canDualWield

◆ m_canModifyStats

bool Unit::m_canModifyStats
protected

◆ m_charmInfo

CharmInfo* Unit::m_charmInfo
protected

◆ m_cleanupDone

bool Unit::m_cleanupDone
private

◆ m_CombatTimer

uint32 Unit::m_CombatTimer
private

◆ m_ComboPointHolders

std::unordered_set<Unit*> Unit::m_ComboPointHolders
private

◆ m_comboPoints

int8 Unit::m_comboPoints
private

◆ m_comboTarget

Unit* Unit::m_comboTarget
private

◆ m_Controlled

ControlSet Unit::m_Controlled

◆ m_ControlledByPlayer

bool Unit::m_ControlledByPlayer

◆ m_CreatedByPlayer

bool Unit::m_CreatedByPlayer

◆ m_createStats

float Unit::m_createStats[MAX_STATS]
protected

◆ m_currentSpells

Spell* Unit::m_currentSpells[CURRENT_MAX_SPELL]
protected

◆ m_deathState

DeathState Unit::m_deathState
protected

◆ m_delayed_unit_ai_notify_timer

uint16 Unit::m_delayed_unit_ai_notify_timer

◆ m_delayed_unit_relocation_timer

uint16 Unit::m_delayed_unit_relocation_timer

◆ m_Diminishing

Diminishing Unit::m_Diminishing
private

◆ m_duringRemoveFromWorld

bool Unit::m_duringRemoveFromWorld
private

◆ m_dynObj

DynObjectList Unit::m_dynObj
protected

◆ m_Events

EventProcessor Unit::m_Events

◆ m_extraAttacks

uint32 Unit::m_extraAttacks

◆ m_FollowingRefMgr

FollowerRefMgr Unit::m_FollowingRefMgr
private

◆ m_gameObj

GameObjectList Unit::m_gameObj
protected

◆ m_HostileRefMgr

HostileRefMgr Unit::m_HostileRefMgr
private

◆ m_interruptableAuras

AuraApplicationList Unit::m_interruptableAuras
protected

◆ m_interruptMask

uint32 Unit::m_interruptMask
protected

◆ m_last_notify_mstime

uint32 Unit::m_last_notify_mstime

◆ m_last_notify_position

Position Unit::m_last_notify_position

◆ m_lastManaUse

uint32 Unit::m_lastManaUse
private

◆ m_lastSanctuaryTime

uint32 Unit::m_lastSanctuaryTime

◆ m_modAttackSpeedPct

float Unit::m_modAttackSpeedPct[3]

◆ m_modAuras

AuraEffectList Unit::m_modAuras[TOTAL_AURAS]
protected

◆ m_modMeleeHitChance

float Unit::m_modMeleeHitChance

◆ m_modRangedHitChance

float Unit::m_modRangedHitChance

◆ m_modSpellHitChance

float Unit::m_modSpellHitChance

◆ m_movedByPlayer

SafeUnitPointer Unit::m_movedByPlayer

◆ m_ObjectSlot

ObjectGuid Unit::m_ObjectSlot[MAX_GAMEOBJECT_SLOT]

◆ m_ownedAuras

AuraMap Unit::m_ownedAuras
protected

◆ m_petAuras

PetAuraSet Unit::m_petAuras

◆ m_procDeep

int32 Unit::m_procDeep
protected

◆ m_race

uint8 Unit::m_race
protected

◆ m_reactiveTimer

uint32 Unit::m_reactiveTimer[MAX_REACTIVE]
protected

◆ m_realRace

uint8 Unit::m_realRace
protected

◆ m_regenTimer

int32 Unit::m_regenTimer
protected

◆ m_removedAuras

AuraList Unit::m_removedAuras
protected

◆ m_removedAurasCount

uint32 Unit::m_removedAurasCount
protected

◆ m_rootTimes

uint32 Unit::m_rootTimes
protected

◆ m_scAuras

AuraList Unit::m_scAuras
protected

◆ m_sharedVision

SharedVisionList Unit::m_sharedVision
protected

◆ m_speed_rate

float Unit::m_speed_rate[MAX_MOVE_TYPE]
protected

◆ m_spellImmune

SpellImmuneList Unit::m_spellImmune[MAX_SPELL_IMMUNITY]

◆ m_state

uint32 Unit::m_state
private

◆ m_SummonSlot

ObjectGuid Unit::m_SummonSlot[MAX_SUMMON_SLOT]

◆ m_ThreatMgr

ThreatMgr Unit::m_ThreatMgr
protected

◆ m_threatModifier

float Unit::m_threatModifier[MAX_SPELL_SCHOOL]

◆ m_transform

uint32 Unit::m_transform
protected

◆ m_unitTypeMask

uint32 Unit::m_unitTypeMask
protected

◆ m_vehicle

Vehicle* Unit::m_vehicle
protected

◆ m_vehicleKit

Vehicle* Unit::m_vehicleKit
protected

◆ m_visibleAuras

VisibleAuraMap Unit::m_visibleAuras
protected

◆ m_weaponDamage

float Unit::m_weaponDamage[MAX_ATTACK][MAX_WEAPON_DAMAGE_RANGE][MAX_ITEM_PROTO_DAMAGES]
protected

◆ movespline

Movement::MoveSpline* Unit::movespline

◆ NeedChangeAI

bool Unit::NeedChangeAI

◆ SafeUnitPointerSet

std::set<SafeUnitPointer*> Unit::SafeUnitPointerSet

The documentation for this class was generated from the following files: